You've already forked AstralRinth
forked from didirus/AstralRinth
Misc testing improvements (#805)
* made dummy data more consistent; not an option * fixed variable dropping issue crashing actix (?) * removed scopes specific tests, removed schedule tests * team routes use api * removed printlns, fmt clippy prepare
This commit is contained in:
@@ -12,7 +12,7 @@ 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, ApiVersion,
|
||||
Api, ApiProject, ApiTags, ApiTeams, ApiUser, ApiVersion,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -71,17 +71,28 @@ delegate_api_variant!(
|
||||
[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>],
|
||||
[schedule_project, ServiceResponse, id_or_slug: &str, requested_status: &str, date : chrono::DateTime<chrono::Utc>, 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>],
|
||||
}
|
||||
);
|
||||
|
||||
@@ -100,6 +111,7 @@ delegate_api_variant!(
|
||||
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>],
|
||||
@@ -110,9 +122,23 @@ delegate_api_variant!(
|
||||
[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>],
|
||||
}
|
||||
);
|
||||
|
||||
@@ -125,6 +151,7 @@ delegate_api_variant!(
|
||||
[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>],
|
||||
|
||||
@@ -7,7 +7,6 @@ use self::models::{
|
||||
use self::request_data::{ImageData, ProjectCreationRequestData};
|
||||
use actix_web::dev::ServiceResponse;
|
||||
use async_trait::async_trait;
|
||||
use chrono::{DateTime, Utc};
|
||||
use labrinth::{
|
||||
models::{
|
||||
projects::{ProjectId, VersionType},
|
||||
@@ -27,7 +26,7 @@ pub trait ApiBuildable: Api {
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
pub trait Api: ApiProject + ApiTags + ApiTeams + ApiVersion {
|
||||
pub trait Api: ApiProject + ApiTags + ApiTeams + ApiUser + ApiVersion {
|
||||
async fn call(&self, req: actix_http::Request) -> ServiceResponse;
|
||||
async fn reset_search_index(&self) -> ServiceResponse;
|
||||
}
|
||||
@@ -59,6 +58,12 @@ pub trait ApiProject {
|
||||
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,
|
||||
@@ -87,13 +92,6 @@ pub trait ApiProject {
|
||||
icon: Option<ImageData>,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn schedule_project(
|
||||
&self,
|
||||
id_or_slug: &str,
|
||||
requested_status: &str,
|
||||
date: DateTime<Utc>,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn add_gallery_item(
|
||||
&self,
|
||||
@@ -127,6 +125,27 @@ pub trait ApiProject {
|
||||
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)]
|
||||
@@ -145,6 +164,7 @@ pub trait ApiTeams {
|
||||
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,
|
||||
@@ -187,11 +207,14 @@ pub trait ApiTeams {
|
||||
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,
|
||||
@@ -205,6 +228,20 @@ pub trait ApiTeams {
|
||||
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)]
|
||||
@@ -227,34 +264,40 @@ pub trait ApiVersion {
|
||||
modify_json: Option<json_patch::Patch>,
|
||||
pat: Option<&str>,
|
||||
) -> CommonVersion;
|
||||
async fn get_version(&self, id_or_slug: &str, pat: Option<&str>) -> ServiceResponse;
|
||||
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_or_slugs: Vec<String>, pat: Option<&str>) -> ServiceResponse;
|
||||
async fn get_versions(&self, ids: Vec<String>, pat: Option<&str>) -> ServiceResponse;
|
||||
async fn get_versions_deserialized_common(
|
||||
&self,
|
||||
ids_or_slugs: Vec<String>,
|
||||
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_or_slug: &str,
|
||||
id: &str,
|
||||
patch: serde_json::Value,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn get_version_from_hash(
|
||||
&self,
|
||||
id_or_slug: &str,
|
||||
hash: &str,
|
||||
algorithm: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn get_version_from_hash_deserialized_common(
|
||||
&self,
|
||||
id_or_slug: &str,
|
||||
hash: &str,
|
||||
algorithm: &str,
|
||||
pat: Option<&str>,
|
||||
) -> CommonVersion;
|
||||
async fn get_versions_from_hashes(
|
||||
|
||||
@@ -13,6 +13,7 @@ pub mod project;
|
||||
pub mod request_data;
|
||||
pub mod tags;
|
||||
pub mod team;
|
||||
pub mod user;
|
||||
pub mod version;
|
||||
|
||||
#[derive(Clone)]
|
||||
|
||||
@@ -15,7 +15,6 @@ use actix_web::{
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use bytes::Bytes;
|
||||
use chrono::{DateTime, Utc};
|
||||
use labrinth::{
|
||||
models::v2::{projects::LegacyProject, search::LegacySearchResults},
|
||||
util::actix::AppendsMultipart,
|
||||
@@ -173,6 +172,30 @@ impl ApiProject for ApiV2 {
|
||||
serde_json::from_value(value).unwrap()
|
||||
}
|
||||
|
||||
async fn get_projects(&self, ids_or_slugs: &[&str], pat: Option<&str>) -> ServiceResponse {
|
||||
let ids_or_slugs = serde_json::to_string(ids_or_slugs).unwrap();
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!(
|
||||
"/v2/projects?ids={encoded}",
|
||||
encoded = urlencoding::encode(&ids_or_slugs)
|
||||
))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn get_project_dependencies(
|
||||
&self,
|
||||
id_or_slug: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let req = TestRequest::get()
|
||||
.uri(&format!("/v2/project/{id_or_slug}/dependencies"))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn get_user_projects(
|
||||
&self,
|
||||
user_id_or_username: &str,
|
||||
@@ -275,7 +298,7 @@ impl ApiProject for ApiV2 {
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let req = test::TestRequest::post()
|
||||
.uri("/v3/report")
|
||||
.uri("/v2/report")
|
||||
.append_pat(pat)
|
||||
.set_json(json!(
|
||||
{
|
||||
@@ -292,28 +315,123 @@ impl ApiProject for ApiV2 {
|
||||
|
||||
async fn get_report(&self, id: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!("/v3/report/{id}", id = id))
|
||||
.uri(&format!("/v2/report/{id}"))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn schedule_project(
|
||||
async fn get_reports(&self, ids: &[&str], pat: Option<&str>) -> ServiceResponse {
|
||||
let ids_str = serde_json::to_string(ids).unwrap();
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!(
|
||||
"/v2/reports?ids={encoded}",
|
||||
encoded = urlencoding::encode(&ids_str)
|
||||
))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn get_user_reports(&self, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/v2/report")
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn delete_report(&self, id: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::delete()
|
||||
.uri(&format!("/v2/report/{id}"))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn edit_report(
|
||||
&self,
|
||||
id_or_slug: &str,
|
||||
requested_status: &str,
|
||||
date: DateTime<Utc>,
|
||||
id: &str,
|
||||
patch: serde_json::Value,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let req = test::TestRequest::patch()
|
||||
.uri(&format!("/v2/report/{id}"))
|
||||
.append_pat(pat)
|
||||
.set_json(patch)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn get_thread(&self, id: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!("/v3/thread/{id}"))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn get_threads(&self, ids: &[&str], pat: Option<&str>) -> ServiceResponse {
|
||||
let ids_str = serde_json::to_string(ids).unwrap();
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!(
|
||||
"/v3/threads?ids={encoded}",
|
||||
encoded = urlencoding::encode(&ids_str)
|
||||
))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn write_to_thread(
|
||||
&self,
|
||||
id: &str,
|
||||
r#type: &str,
|
||||
content: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let req = test::TestRequest::post()
|
||||
.uri(&format!("/v2/version/{id_or_slug}/schedule"))
|
||||
.set_json(json!(
|
||||
{
|
||||
"requested_status": requested_status,
|
||||
"time": date,
|
||||
.uri(&format!("/v2/thread/{id}"))
|
||||
.append_pat(pat)
|
||||
.set_json(json!({
|
||||
"body" : {
|
||||
"type": r#type,
|
||||
"body": content,
|
||||
}
|
||||
))
|
||||
}))
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn get_moderation_inbox(&self, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/v2/thread/inbox")
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn read_thread(&self, id: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::post()
|
||||
.uri(&format!("/v2/thread/{id}/read"))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn delete_thread_message(&self, id: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::delete()
|
||||
.uri(&format!("/v2/message/{id}"))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
|
||||
@@ -72,6 +72,22 @@ impl ApiTeams for ApiV2 {
|
||||
test::read_body_json(resp).await
|
||||
}
|
||||
|
||||
async fn get_teams_members(
|
||||
&self,
|
||||
ids_or_titles: &[&str],
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let ids_or_titles = serde_json::to_string(ids_or_titles).unwrap();
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!(
|
||||
"/v2/teams?ids={}",
|
||||
urlencoding::encode(&ids_or_titles)
|
||||
))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn get_project_members(&self, id_or_title: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!("/v2/project/{id_or_title}/members"))
|
||||
@@ -192,6 +208,30 @@ impl ApiTeams for ApiV2 {
|
||||
serde_json::from_value(value).unwrap()
|
||||
}
|
||||
|
||||
async fn get_notification(&self, notification_id: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!("/v2/notification/{notification_id}"))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn get_notifications(
|
||||
&self,
|
||||
notification_ids: &[&str],
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let notification_ids = serde_json::to_string(notification_ids).unwrap();
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!(
|
||||
"/v2/notifications?ids={}",
|
||||
urlencoding::encode(¬ification_ids)
|
||||
))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn mark_notification_read(
|
||||
&self,
|
||||
notification_id: &str,
|
||||
@@ -204,6 +244,22 @@ impl ApiTeams for ApiV2 {
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn mark_notifications_read(
|
||||
&self,
|
||||
notification_ids: &[&str],
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let notification_ids = serde_json::to_string(notification_ids).unwrap();
|
||||
let req = test::TestRequest::patch()
|
||||
.uri(&format!(
|
||||
"/v2/notifications?ids={}",
|
||||
urlencoding::encode(¬ification_ids)
|
||||
))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn add_user_to_team(
|
||||
&self,
|
||||
team_id: &str,
|
||||
@@ -235,4 +291,20 @@ impl ApiTeams for ApiV2 {
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn delete_notifications(
|
||||
&self,
|
||||
notification_ids: &[&str],
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let notification_ids = serde_json::to_string(notification_ids).unwrap();
|
||||
let req = test::TestRequest::delete()
|
||||
.uri(&format!(
|
||||
"/v2/notifications?ids={}",
|
||||
urlencoding::encode(¬ification_ids)
|
||||
))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
}
|
||||
|
||||
47
tests/common/api_v2/user.rs
Normal file
47
tests/common/api_v2/user.rs
Normal file
@@ -0,0 +1,47 @@
|
||||
use super::ApiV2;
|
||||
use crate::common::api_common::{Api, ApiUser, AppendsOptionalPat};
|
||||
use actix_web::{dev::ServiceResponse, test};
|
||||
use async_trait::async_trait;
|
||||
|
||||
#[async_trait(?Send)]
|
||||
impl ApiUser for ApiV2 {
|
||||
async fn get_user(&self, user_id_or_username: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!("/v2/user/{}", user_id_or_username))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn get_current_user(&self, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/v2/user")
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn edit_user(
|
||||
&self,
|
||||
user_id_or_username: &str,
|
||||
patch: serde_json::Value,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let req = test::TestRequest::patch()
|
||||
.uri(&format!("/v2/user/{}", user_id_or_username))
|
||||
.append_pat(pat)
|
||||
.set_json(patch)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn delete_user(&self, user_id_or_username: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::delete()
|
||||
.uri(&format!("/v2/user/{}", user_id_or_username))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
}
|
||||
@@ -161,6 +161,22 @@ impl ApiVersion for ApiV2 {
|
||||
serde_json::from_value(value).unwrap()
|
||||
}
|
||||
|
||||
async fn download_version_redirect(
|
||||
&self,
|
||||
hash: &str,
|
||||
algorithm: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!("/v2/version_file/{hash}/download",))
|
||||
.set_json(json!({
|
||||
"algorithm": algorithm,
|
||||
}))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn edit_version(
|
||||
&self,
|
||||
version_id: &str,
|
||||
|
||||
155
tests/common/api_v3/collections.rs
Normal file
155
tests/common/api_v3/collections.rs
Normal file
@@ -0,0 +1,155 @@
|
||||
use actix_web::{
|
||||
dev::ServiceResponse,
|
||||
test::{self, TestRequest},
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use labrinth::models::{collections::Collection, v3::projects::Project};
|
||||
use serde_json::json;
|
||||
|
||||
use crate::common::api_common::{request_data::ImageData, Api, AppendsOptionalPat};
|
||||
|
||||
use super::ApiV3;
|
||||
|
||||
impl ApiV3 {
|
||||
pub async fn create_collection(
|
||||
&self,
|
||||
collection_title: &str,
|
||||
description: &str,
|
||||
projects: &[&str],
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let req = test::TestRequest::post()
|
||||
.uri("/v3/collection")
|
||||
.append_pat(pat)
|
||||
.set_json(json!({
|
||||
"name": collection_title,
|
||||
"description": description,
|
||||
"projects": projects,
|
||||
}))
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
pub async fn get_collection(&self, id: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = TestRequest::get()
|
||||
.uri(&format!("/v3/collection/{id}"))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
pub async fn get_collection_deserialized(&self, id: &str, pat: Option<&str>) -> Collection {
|
||||
let resp = self.get_collection(id, pat).await;
|
||||
assert_eq!(resp.status(), 200);
|
||||
test::read_body_json(resp).await
|
||||
}
|
||||
|
||||
pub async fn get_collections(&self, ids: &[&str], pat: Option<&str>) -> ServiceResponse {
|
||||
let ids = serde_json::to_string(ids).unwrap();
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!(
|
||||
"/v3/collections?ids={}",
|
||||
urlencoding::encode(&ids)
|
||||
))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
pub async fn get_collection_projects(&self, id: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!("/v3/collection/{id}/projects"))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
pub async fn get_collection_projects_deserialized(
|
||||
&self,
|
||||
id: &str,
|
||||
pat: Option<&str>,
|
||||
) -> Vec<Project> {
|
||||
let resp = self.get_collection_projects(id, pat).await;
|
||||
assert_eq!(resp.status(), 200);
|
||||
test::read_body_json(resp).await
|
||||
}
|
||||
|
||||
pub async fn edit_collection(
|
||||
&self,
|
||||
id: &str,
|
||||
patch: serde_json::Value,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let req = test::TestRequest::patch()
|
||||
.uri(&format!("/v3/collection/{id}"))
|
||||
.append_pat(pat)
|
||||
.set_json(patch)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
pub async fn edit_collection_icon(
|
||||
&self,
|
||||
id: &str,
|
||||
icon: Option<ImageData>,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
if let Some(icon) = icon {
|
||||
// If an icon is provided, upload it
|
||||
let req = test::TestRequest::patch()
|
||||
.uri(&format!(
|
||||
"/v3/collection/{id}/icon?ext={ext}",
|
||||
ext = icon.extension
|
||||
))
|
||||
.append_pat(pat)
|
||||
.set_payload(Bytes::from(icon.icon))
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
} else {
|
||||
// If no icon is provided, delete the icon
|
||||
let req = test::TestRequest::delete()
|
||||
.uri(&format!("/v3/collection/{id}/icon"))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn delete_collection(&self, id: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::delete()
|
||||
.uri(&format!("/v3/collection/{id}"))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
pub async fn get_user_collections(
|
||||
&self,
|
||||
user_id_or_username: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!("/v3/user/{}/collections", user_id_or_username))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
pub async fn get_user_collections_deserialized_common(
|
||||
&self,
|
||||
user_id_or_username: &str,
|
||||
pat: Option<&str>,
|
||||
) -> Vec<Collection> {
|
||||
let resp = self.get_user_collections(user_id_or_username, pat).await;
|
||||
assert_eq!(resp.status(), 200);
|
||||
// First, deserialize to the non-common format (to test the response is valid for this api version)
|
||||
let projects: Vec<Project> = test::read_body_json(resp).await;
|
||||
// Then, deserialize to the common format
|
||||
let value = serde_json::to_value(projects).unwrap();
|
||||
serde_json::from_value(value).unwrap()
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ use async_trait::async_trait;
|
||||
use labrinth::LabrinthConfig;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub mod collections;
|
||||
pub mod oauth;
|
||||
pub mod oauth_clients;
|
||||
pub mod organization;
|
||||
@@ -16,6 +17,7 @@ pub mod project;
|
||||
pub mod request_data;
|
||||
pub mod tags;
|
||||
pub mod team;
|
||||
pub mod user;
|
||||
pub mod version;
|
||||
|
||||
#[derive(Clone)]
|
||||
|
||||
@@ -46,6 +46,22 @@ impl ApiV3 {
|
||||
test::read_body_json(resp).await
|
||||
}
|
||||
|
||||
pub async fn get_organizations(
|
||||
&self,
|
||||
ids_or_titles: &[&str],
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let ids_or_titles = serde_json::to_string(ids_or_titles).unwrap();
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!(
|
||||
"/v3/organizations?ids={}",
|
||||
urlencoding::encode(&ids_or_titles)
|
||||
))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
pub async fn get_organization_projects(
|
||||
&self,
|
||||
id_or_title: &str,
|
||||
|
||||
@@ -126,6 +126,30 @@ impl ApiProject for ApiV3 {
|
||||
serde_json::from_value(value).unwrap()
|
||||
}
|
||||
|
||||
async fn get_projects(&self, ids_or_slugs: &[&str], pat: Option<&str>) -> ServiceResponse {
|
||||
let ids_or_slugs = serde_json::to_string(ids_or_slugs).unwrap();
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!(
|
||||
"/v2/projects?ids={encoded}",
|
||||
encoded = urlencoding::encode(&ids_or_slugs)
|
||||
))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn get_project_dependencies(
|
||||
&self,
|
||||
id_or_slug: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let req = TestRequest::get()
|
||||
.uri(&format!("/v2/project/{id_or_slug}/dependencies"))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn get_user_projects(
|
||||
&self,
|
||||
user_id_or_username: &str,
|
||||
@@ -245,28 +269,53 @@ impl ApiProject for ApiV3 {
|
||||
|
||||
async fn get_report(&self, id: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!("/v3/report/{id}", id = id))
|
||||
.uri(&format!("/v3/report/{id}"))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn schedule_project(
|
||||
async fn get_reports(&self, ids: &[&str], pat: Option<&str>) -> ServiceResponse {
|
||||
let ids_str = serde_json::to_string(ids).unwrap();
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!(
|
||||
"/v3/reports?ids={encoded}",
|
||||
encoded = urlencoding::encode(&ids_str)
|
||||
))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn get_user_reports(&self, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/v3/report")
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn edit_report(
|
||||
&self,
|
||||
id_or_slug: &str,
|
||||
requested_status: &str,
|
||||
date: DateTime<Utc>,
|
||||
id: &str,
|
||||
patch: serde_json::Value,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let req = test::TestRequest::post()
|
||||
.uri(&format!("/v3/version/{id_or_slug}/schedule"))
|
||||
.set_json(json!(
|
||||
{
|
||||
"requested_status": requested_status,
|
||||
"time": date,
|
||||
}
|
||||
))
|
||||
let req = test::TestRequest::patch()
|
||||
.uri(&format!("/v3/report/{id}"))
|
||||
.append_pat(pat)
|
||||
.set_json(patch)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn delete_report(&self, id: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::delete()
|
||||
.uri(&format!("/v3/report/{id}"))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
@@ -355,6 +404,76 @@ impl ApiProject for ApiV3 {
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn get_thread(&self, id: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!("/v3/thread/{id}"))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn get_threads(&self, ids: &[&str], pat: Option<&str>) -> ServiceResponse {
|
||||
let ids_str = serde_json::to_string(ids).unwrap();
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!(
|
||||
"/v3/threads?ids={encoded}",
|
||||
encoded = urlencoding::encode(&ids_str)
|
||||
))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn write_to_thread(
|
||||
&self,
|
||||
id: &str,
|
||||
r#type: &str,
|
||||
content: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let req = test::TestRequest::post()
|
||||
.uri(&format!("/v3/thread/{id}"))
|
||||
.append_pat(pat)
|
||||
.set_json(json!({
|
||||
"body": {
|
||||
"type": r#type,
|
||||
"body": content
|
||||
}
|
||||
}))
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn get_moderation_inbox(&self, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/v3/thread/inbox")
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn read_thread(&self, id: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::post()
|
||||
.uri(&format!("/v3/thread/{id}/read"))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn delete_thread_message(&self, id: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::delete()
|
||||
.uri(&format!("/v3/message/{id}"))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiV3 {
|
||||
|
||||
@@ -63,6 +63,22 @@ impl ApiTeams for ApiV3 {
|
||||
serde_json::from_value(value).unwrap()
|
||||
}
|
||||
|
||||
async fn get_teams_members(
|
||||
&self,
|
||||
ids_or_titles: &[&str],
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let ids_or_titles = serde_json::to_string(ids_or_titles).unwrap();
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!(
|
||||
"/v3/teams?ids={}",
|
||||
urlencoding::encode(&ids_or_titles)
|
||||
))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn get_project_members(&self, id_or_title: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!("/v3/project/{id_or_title}/members"))
|
||||
@@ -185,6 +201,30 @@ impl ApiTeams for ApiV3 {
|
||||
serde_json::from_value(value).unwrap()
|
||||
}
|
||||
|
||||
async fn get_notification(&self, notification_id: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!("/v3/notification/{notification_id}"))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn get_notifications(
|
||||
&self,
|
||||
notification_ids: &[&str],
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let notification_ids = serde_json::to_string(notification_ids).unwrap();
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!(
|
||||
"/v3/notifications?ids={}",
|
||||
urlencoding::encode(¬ification_ids)
|
||||
))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn mark_notification_read(
|
||||
&self,
|
||||
notification_id: &str,
|
||||
@@ -196,6 +236,23 @@ impl ApiTeams for ApiV3 {
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn mark_notifications_read(
|
||||
&self,
|
||||
notification_ids: &[&str],
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let notification_ids = serde_json::to_string(notification_ids).unwrap();
|
||||
let req = test::TestRequest::patch()
|
||||
.uri(&format!(
|
||||
"/v3/notifications?ids={}",
|
||||
urlencoding::encode(¬ification_ids)
|
||||
))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn add_user_to_team(
|
||||
&self,
|
||||
team_id: &str,
|
||||
@@ -227,4 +284,20 @@ impl ApiTeams for ApiV3 {
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn delete_notifications(
|
||||
&self,
|
||||
notification_ids: &[&str],
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let notification_ids = serde_json::to_string(notification_ids).unwrap();
|
||||
let req = test::TestRequest::delete()
|
||||
.uri(&format!(
|
||||
"/v3/notifications?ids={}",
|
||||
urlencoding::encode(¬ification_ids)
|
||||
))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
}
|
||||
|
||||
48
tests/common/api_v3/user.rs
Normal file
48
tests/common/api_v3/user.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
use actix_web::{dev::ServiceResponse, test};
|
||||
use async_trait::async_trait;
|
||||
|
||||
use crate::common::api_common::{Api, ApiUser, AppendsOptionalPat};
|
||||
|
||||
use super::ApiV3;
|
||||
|
||||
#[async_trait(?Send)]
|
||||
impl ApiUser for ApiV3 {
|
||||
async fn get_user(&self, user_id_or_username: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!("/v3/user/{}", user_id_or_username))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn get_current_user(&self, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/v3/user")
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn edit_user(
|
||||
&self,
|
||||
user_id_or_username: &str,
|
||||
patch: serde_json::Value,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let req = test::TestRequest::patch()
|
||||
.uri(&format!("/v3/user/{}", user_id_or_username))
|
||||
.append_pat(pat)
|
||||
.set_json(patch)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn delete_user(&self, user_id_or_username: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::delete()
|
||||
.uri(&format!("/v3/user/{}", user_id_or_username))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
}
|
||||
@@ -181,6 +181,22 @@ impl ApiVersion for ApiV3 {
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn download_version_redirect(
|
||||
&self,
|
||||
hash: &str,
|
||||
algorithm: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!("/v3/version_file/{hash}/download",))
|
||||
.set_json(json!({
|
||||
"algorithm": algorithm,
|
||||
}))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn get_version_from_hash(
|
||||
&self,
|
||||
hash: &str,
|
||||
|
||||
@@ -168,21 +168,14 @@ impl TemporaryDatabase {
|
||||
|
||||
if !dummy_data_exists {
|
||||
// Add dummy data
|
||||
let temporary_test_env =
|
||||
TestEnvironment::<ApiV3>::build_with_db(TemporaryDatabase {
|
||||
pool: pool.clone(),
|
||||
database_name: TEMPLATE_DATABASE_NAME.to_string(),
|
||||
redis_pool: RedisPool::new(Some(generate_random_name(
|
||||
"test_template_",
|
||||
))),
|
||||
})
|
||||
.await;
|
||||
dummy_data::add_dummy_data(
|
||||
&temporary_test_env.setup_api,
|
||||
temporary_test_env.db.clone(),
|
||||
)
|
||||
.await;
|
||||
temporary_test_env.db.pool.close().await;
|
||||
let db = TemporaryDatabase {
|
||||
pool: pool.clone(),
|
||||
database_name: TEMPLATE_DATABASE_NAME.to_string(),
|
||||
redis_pool: RedisPool::new(Some(generate_random_name("test_template_"))),
|
||||
};
|
||||
let setup_api = TestEnvironment::<ApiV3>::build_setup_api(&db).await;
|
||||
dummy_data::add_dummy_data(&setup_api, db.clone()).await;
|
||||
db.pool.close().await;
|
||||
}
|
||||
pool.close().await;
|
||||
drop(pool);
|
||||
|
||||
@@ -65,33 +65,30 @@ where
|
||||
// Use .call(req) on it directly to make a test call as if test::call_service(req) were being used.
|
||||
#[derive(Clone)]
|
||||
pub struct TestEnvironment<A> {
|
||||
// test_app: Rc<dyn LocalService>, // Rc as it's not Send
|
||||
pub db: TemporaryDatabase,
|
||||
pub api: A,
|
||||
pub setup_api: ApiV3, // Used for setting up tests only (ie: in ScopesTest)
|
||||
pub dummy: Option<dummy_data::DummyData>,
|
||||
pub dummy: dummy_data::DummyData,
|
||||
}
|
||||
|
||||
impl<A: ApiBuildable> TestEnvironment<A> {
|
||||
async fn build(max_connections: Option<u32>) -> Self {
|
||||
let db = TemporaryDatabase::create(max_connections).await;
|
||||
let mut test_env = Self::build_with_db(db).await;
|
||||
|
||||
let dummy = dummy_data::get_dummy_data(&test_env.setup_api).await;
|
||||
test_env.dummy = Some(dummy);
|
||||
test_env
|
||||
}
|
||||
|
||||
pub async fn build_with_db(db: TemporaryDatabase) -> Self {
|
||||
let labrinth_config = setup(&db).await;
|
||||
let api = A::build(labrinth_config.clone()).await;
|
||||
let setup_api = ApiV3::build(labrinth_config).await;
|
||||
let dummy = dummy_data::get_dummy_data(&setup_api).await;
|
||||
Self {
|
||||
db,
|
||||
api: A::build(labrinth_config.clone()).await,
|
||||
setup_api: ApiV3::build(labrinth_config.clone()).await,
|
||||
dummy: None,
|
||||
// test_app
|
||||
api,
|
||||
setup_api,
|
||||
dummy,
|
||||
}
|
||||
}
|
||||
pub async fn build_setup_api(db: &TemporaryDatabase) -> ApiV3 {
|
||||
let labrinth_config = setup(db).await;
|
||||
ApiV3::build(labrinth_config).await
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Api> TestEnvironment<A> {
|
||||
@@ -108,7 +105,7 @@ impl<A: Api> TestEnvironment<A> {
|
||||
let resp = self
|
||||
.api
|
||||
.add_user_to_team(
|
||||
&self.dummy.as_ref().unwrap().project_alpha.team_id,
|
||||
&self.dummy.project_alpha.team_id,
|
||||
FRIEND_USER_ID,
|
||||
None,
|
||||
None,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#![allow(dead_code)]
|
||||
use actix_web::test::{self, TestRequest};
|
||||
use actix_web::{dev::ServiceResponse, test};
|
||||
use futures::Future;
|
||||
use labrinth::models::pats::Scopes;
|
||||
|
||||
use super::{
|
||||
@@ -59,13 +60,14 @@ impl<'a, A: Api> ScopeTest<'a, A> {
|
||||
// success_scopes : the scopes that we are testing that should succeed
|
||||
// returns a tuple of (failure_body, success_body)
|
||||
// Should return a String error if on unexpected status code, allowing unwrapping in tests.
|
||||
pub async fn test<T>(
|
||||
pub async fn test<T, Fut>(
|
||||
&self,
|
||||
req_gen: T,
|
||||
success_scopes: Scopes,
|
||||
) -> Result<(serde_json::Value, serde_json::Value), String>
|
||||
where
|
||||
T: Fn() -> TestRequest,
|
||||
T: Fn(Option<String>) -> Fut,
|
||||
Fut: Future<Output = ServiceResponse>, // Ensure Fut is Send and 'static
|
||||
{
|
||||
// First, create a PAT with failure scopes
|
||||
let failure_scopes = self
|
||||
@@ -79,11 +81,7 @@ impl<'a, A: Api> ScopeTest<'a, A> {
|
||||
|
||||
// Perform test twice, once with each PAT
|
||||
// the first time, we expect a 401 (or known failure code)
|
||||
let req = req_gen()
|
||||
.append_header(("Authorization", access_token_all_others.as_str()))
|
||||
.to_request();
|
||||
let resp = self.test_env.call(req).await;
|
||||
|
||||
let resp = req_gen(Some(access_token_all_others.clone())).await;
|
||||
if resp.status().as_u16() != self.expected_failure_code {
|
||||
return Err(format!(
|
||||
"Expected failure code {}, got {} ({:#?})",
|
||||
@@ -103,11 +101,7 @@ impl<'a, A: Api> ScopeTest<'a, A> {
|
||||
};
|
||||
|
||||
// The second time, we expect a success code
|
||||
let req = req_gen()
|
||||
.append_header(("Authorization", access_token.as_str()))
|
||||
.to_request();
|
||||
let resp = self.test_env.call(req).await;
|
||||
|
||||
let resp = req_gen(Some(access_token.clone())).await;
|
||||
if !(resp.status().is_success() || resp.status().is_redirection()) {
|
||||
return Err(format!(
|
||||
"Expected success code, got {} ({:#?})",
|
||||
|
||||
Reference in New Issue
Block a user