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:
Wyatt Verchere
2023-12-20 11:46:53 -08:00
committed by GitHub
parent d59c522f7f
commit 60c535e861
39 changed files with 1775 additions and 1436 deletions

View File

@@ -9,8 +9,7 @@ use crate::models::v2::projects::LegacyVersion;
use crate::queue::session::AuthQueue;
use crate::routes::{v2_reroute, v3};
use crate::search::SearchConfig;
use actix_web::{delete, get, patch, post, web, HttpRequest, HttpResponse};
use chrono::{DateTime, Utc};
use actix_web::{delete, get, patch, web, HttpRequest, HttpResponse};
use serde::{Deserialize, Serialize};
use sqlx::PgPool;
use validator::Validate;
@@ -24,7 +23,6 @@ pub fn config(cfg: &mut web::ServiceConfig) {
.service(version_get)
.service(version_delete)
.service(version_edit)
.service(version_schedule)
.service(super::version_creation::upload_file_to_version),
);
}
@@ -275,36 +273,3 @@ pub async fn version_delete(
.await
.or_else(v2_reroute::flatten_404_error)
}
#[derive(Deserialize)]
pub struct SchedulingData {
pub time: DateTime<Utc>,
pub requested_status: VersionStatus,
}
#[post("{id}/schedule")]
pub async fn version_schedule(
req: HttpRequest,
info: web::Path<(VersionId,)>,
pool: web::Data<PgPool>,
redis: web::Data<RedisPool>,
scheduling_data: web::Json<SchedulingData>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
// Returns NoContent, so we don't need to convert the response
let scheduling_data = scheduling_data.into_inner();
let scheduling_data = v3::versions::SchedulingData {
time: scheduling_data.time,
requested_status: scheduling_data.requested_status,
};
v3::versions::version_schedule(
req,
info,
pool,
redis,
web::Json(scheduling_data),
session_queue,
)
.await
.or_else(v2_reroute::flatten_404_error)
}

View File

@@ -27,7 +27,7 @@ use crate::util::img;
use crate::util::routes::read_from_payload;
use crate::util::validate::validation_errors_to_string;
use actix_web::{web, HttpRequest, HttpResponse};
use chrono::{DateTime, Utc};
use chrono::Utc;
use futures::TryStreamExt;
use itertools::Itertools;
use serde::{Deserialize, Serialize};
@@ -54,7 +54,6 @@ pub fn config(cfg: &mut web::ServiceConfig) {
.route("{id}/gallery", web::delete().to(delete_gallery_item))
.route("{id}/follow", web::post().to(project_follow))
.route("{id}/follow", web::delete().to(project_unfollow))
.route("{id}/schedule", web::post().to(project_schedule))
.service(
web::scope("{project_id}")
.route(
@@ -1305,100 +1304,6 @@ pub async fn bulk_edit_project_categories(
Ok(())
}
#[derive(Deserialize)]
pub struct SchedulingData {
pub time: DateTime<Utc>,
pub requested_status: ProjectStatus,
}
pub async fn project_schedule(
req: HttpRequest,
info: web::Path<(String,)>,
pool: web::Data<PgPool>,
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
scheduling_data: web::Json<SchedulingData>,
) -> Result<HttpResponse, ApiError> {
let user = get_user_from_headers(
&req,
&**pool,
&redis,
&session_queue,
Some(&[Scopes::PROJECT_WRITE]),
)
.await?
.1;
if scheduling_data.time < Utc::now() {
return Err(ApiError::InvalidInput(
"You cannot schedule a project to be released in the past!".to_string(),
));
}
if !scheduling_data.requested_status.can_be_requested() {
return Err(ApiError::InvalidInput(
"Specified requested status cannot be requested!".to_string(),
));
}
let string = info.into_inner().0;
let result = db_models::Project::get(&string, &**pool, &redis).await?;
if let Some(project_item) = result {
let (team_member, organization_team_member) =
db_models::TeamMember::get_for_project_permissions(
&project_item.inner,
user.id.into(),
&**pool,
)
.await?;
let permissions = ProjectPermissions::get_permissions_by_role(
&user.role,
&team_member.clone(),
&organization_team_member.clone(),
)
.unwrap_or_default();
if !user.role.is_mod() && !permissions.contains(ProjectPermissions::EDIT_DETAILS) {
return Err(ApiError::CustomAuthentication(
"You do not have permission to edit this project's scheduling data!".to_string(),
));
}
if !project_item.inner.status.is_approved() {
return Err(ApiError::InvalidInput(
"This project has not been approved yet. Submit to the queue with the private status to schedule it in the future!".to_string(),
));
}
sqlx::query!(
"
UPDATE mods
SET status = $1, approved = $2
WHERE (id = $3)
",
ProjectStatus::Scheduled.as_str(),
scheduling_data.time,
project_item.inner.id as db_ids::ProjectId,
)
.execute(&**pool)
.await?;
db_models::Project::clear_cache(
project_item.inner.id,
project_item.inner.slug,
None,
&redis,
)
.await?;
Ok(HttpResponse::NoContent().body(""))
} else {
Err(ApiError::NotFound)
}
}
#[derive(Serialize, Deserialize)]
pub struct Extension {
pub ext: String,

View File

@@ -25,7 +25,6 @@ use crate::search::SearchConfig;
use crate::util::img;
use crate::util::validate::validation_errors_to_string;
use actix_web::{web, HttpRequest, HttpResponse};
use chrono::{DateTime, Utc};
use itertools::Itertools;
use serde::{Deserialize, Serialize};
use sqlx::PgPool;
@@ -43,7 +42,6 @@ pub fn config(cfg: &mut web::ServiceConfig) {
.route("{id}", web::get().to(version_get))
.route("{id}", web::patch().to(version_edit))
.route("{id}", web::delete().to(version_delete))
.route("{id}/schedule", web::post().to(version_schedule))
.route(
"{version_id}/file",
web::post().to(super::version_creation::upload_file_to_version),
@@ -828,108 +826,6 @@ pub async fn version_list(
}
}
#[derive(Deserialize)]
pub struct SchedulingData {
pub time: DateTime<Utc>,
pub requested_status: VersionStatus,
}
pub async fn version_schedule(
req: HttpRequest,
info: web::Path<(models::ids::VersionId,)>,
pool: web::Data<PgPool>,
redis: web::Data<RedisPool>,
scheduling_data: web::Json<SchedulingData>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
let user = get_user_from_headers(
&req,
&**pool,
&redis,
&session_queue,
Some(&[Scopes::VERSION_WRITE]),
)
.await?
.1;
if scheduling_data.time < Utc::now() {
return Err(ApiError::InvalidInput(
"You cannot schedule a version to be released in the past!".to_string(),
));
}
if !scheduling_data.requested_status.can_be_requested() {
return Err(ApiError::InvalidInput(
"Specified requested status cannot be requested!".to_string(),
));
}
let string = info.into_inner().0;
let result = database::models::Version::get(string.into(), &**pool, &redis).await?;
if let Some(version_item) = result {
let team_member = database::models::TeamMember::get_from_user_id_project(
version_item.inner.project_id,
user.id.into(),
&**pool,
)
.await?;
let organization_item =
database::models::Organization::get_associated_organization_project_id(
version_item.inner.project_id,
&**pool,
)
.await
.map_err(ApiError::Database)?;
let organization_team_member = if let Some(organization) = &organization_item {
database::models::TeamMember::get_from_user_id(
organization.team_id,
user.id.into(),
&**pool,
)
.await?
} else {
None
};
let permissions = ProjectPermissions::get_permissions_by_role(
&user.role,
&team_member,
&organization_team_member,
)
.unwrap_or_default();
if !user.role.is_mod() && !permissions.contains(ProjectPermissions::EDIT_DETAILS) {
return Err(ApiError::CustomAuthentication(
"You do not have permission to edit this version's scheduling data!".to_string(),
));
}
let mut transaction = pool.begin().await?;
sqlx::query!(
"
UPDATE versions
SET status = $1, date_published = $2
WHERE (id = $3)
",
VersionStatus::Scheduled.as_str(),
scheduling_data.time,
version_item.inner.id as database::models::ids::VersionId,
)
.execute(&mut *transaction)
.await?;
transaction.commit().await?;
database::models::Version::clear_cache(&version_item, &redis).await?;
Ok(HttpResponse::NoContent().body(""))
} else {
Err(ApiError::NotFound)
}
}
pub async fn version_delete(
req: HttpRequest,
info: web::Path<(models::ids::VersionId,)>,