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:
Wyatt Verchere
2023-11-25 13:42:39 -08:00
committed by GitHub
parent ade8c162cd
commit 172b93d07f
51 changed files with 7573 additions and 6631 deletions

View File

@@ -1,101 +1,39 @@
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_web::{
dev::ServiceResponse,
test::{self, TestRequest},
};
use async_trait::async_trait;
use labrinth::{
models::{projects::VersionType, v2::projects::LegacyVersion},
models::{
projects::{ProjectId, VersionType},
v2::projects::LegacyVersion,
},
routes::v2::version_file::FileUpdateData,
util::actix::AppendsMultipart,
};
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 {
let serialized = serde_json::to_string(&elements).unwrap();
urlencoding::encode(&serialized).to_string()
}
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 {
let resp = self.get_version(id, pat).await;
assert_eq!(resp.status(), 200);
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(
&self,
hash: &str,
@@ -107,23 +45,6 @@ impl ApiV2 {
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(
&self,
hashes: &[&str],
@@ -135,91 +56,6 @@ impl ApiV2 {
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(
&self,
algorithm: &str,
@@ -247,10 +83,228 @@ impl ApiV2 {
assert_eq!(resp.status(), 200);
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
#[allow(clippy::too_many_arguments)]
pub async fn get_project_versions(
async fn get_project_versions(
&self,
project_id_slug: &str,
game_versions: Option<Vec<String>>,
@@ -300,7 +354,7 @@ impl ApiV2 {
}
#[allow(clippy::too_many_arguments)]
pub async fn get_project_versions_deserialized(
async fn get_project_versions_deserialized_common(
&self,
slug: &str,
game_versions: Option<Vec<String>>,
@@ -310,7 +364,7 @@ impl ApiV2 {
limit: Option<usize>,
offset: Option<usize>,
pat: &str,
) -> Vec<LegacyVersion> {
) -> Vec<CommonVersion> {
let resp = self
.get_project_versions(
slug,
@@ -327,66 +381,7 @@ impl ApiV2 {
test::read_body_json(resp).await
}
// TODO: remove redundancy in these functions- some are essentially repeats
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(
async fn edit_version_ordering(
&self,
version_id: &str,
ordering: Option<i32>,
@@ -403,4 +398,23 @@ impl ApiV2 {
.to_request();
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
}
}