You've already forked AstralRinth
forked from didirus/AstralRinth
Expose test utils to Labrinth dependents (#4703)
* Expose test utils to Labrinth dependents * Feature gate `labrinth::test` * Unify db migrators * Expose `NotificationBuilder::insert_many_deliveries` * Add logging utils to common crate * Remove unused console-subscriber layer * fix CI
This commit is contained in:
@@ -1,9 +1,6 @@
|
||||
[build]
|
||||
rustflags = ["--cfg", "tokio_unstable"]
|
||||
|
||||
# Windows has stack overflows when calling from Tauri, so we increase the default stack size used by the compiler
|
||||
[target.'cfg(windows)']
|
||||
rustflags = ["--cfg", "tokio_unstable", "-C", "link-args=/STACK:16777220"]
|
||||
rustflags = ["-C", "link-args=/STACK:16777220"]
|
||||
|
||||
[target.x86_64-pc-windows-msvc]
|
||||
linker = "rust-lld"
|
||||
|
||||
217
Cargo.lock
generated
217
Cargo.lock
generated
@@ -671,28 +671,6 @@ dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-stream"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476"
|
||||
dependencies = [
|
||||
"async-stream-impl",
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-stream-impl"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.106",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-stripe"
|
||||
version = "0.41.0"
|
||||
@@ -914,53 +892,6 @@ dependencies = [
|
||||
"thiserror 2.0.17",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum"
|
||||
version = "0.7.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum-core",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http 1.3.1",
|
||||
"http-body 1.0.1",
|
||||
"http-body-util",
|
||||
"itoa",
|
||||
"matchit",
|
||||
"memchr",
|
||||
"mime",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustversion",
|
||||
"serde",
|
||||
"sync_wrapper",
|
||||
"tower 0.5.2",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum-core"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http 1.3.1",
|
||||
"http-body 1.0.1",
|
||||
"http-body-util",
|
||||
"mime",
|
||||
"pin-project-lite",
|
||||
"rustversion",
|
||||
"sync_wrapper",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.76"
|
||||
@@ -1697,45 +1628,6 @@ dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "console-api"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8030735ecb0d128428b64cd379809817e620a40e5001c54465b99ec5feec2857"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"tonic",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "console-subscriber"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6539aa9c6a4cd31f4b1c040f860a1eac9aa80e7df6b05d506a6e7179936d6a01"
|
||||
dependencies = [
|
||||
"console-api",
|
||||
"crossbeam-channel",
|
||||
"crossbeam-utils",
|
||||
"futures-task",
|
||||
"hdrhistogram",
|
||||
"humantime",
|
||||
"hyper-util",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thread_local",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tonic",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const-oid"
|
||||
version = "0.9.6"
|
||||
@@ -3647,19 +3539,6 @@ dependencies = [
|
||||
"hashbrown 0.15.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hdrhistogram"
|
||||
version = "7.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"byteorder",
|
||||
"flate2",
|
||||
"nom 7.1.3",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
@@ -3875,12 +3754,6 @@ version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.14.32"
|
||||
@@ -3962,19 +3835,6 @@ dependencies = [
|
||||
"webpki-roots 1.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-timeout"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0"
|
||||
dependencies = [
|
||||
"hyper 1.7.0",
|
||||
"hyper-util",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-tls"
|
||||
version = "0.6.0"
|
||||
@@ -4660,7 +4520,6 @@ dependencies = [
|
||||
"clickhouse",
|
||||
"color-eyre",
|
||||
"color-thief",
|
||||
"console-subscriber",
|
||||
"const_format",
|
||||
"dashmap",
|
||||
"deadpool-redis",
|
||||
@@ -4679,9 +4538,11 @@ dependencies = [
|
||||
"itertools 0.14.0",
|
||||
"jemalloc_pprof",
|
||||
"json-patch 4.1.0",
|
||||
"labrinth",
|
||||
"lettre",
|
||||
"meilisearch-sdk",
|
||||
"modrinth-maxmind",
|
||||
"modrinth-util",
|
||||
"muralpay",
|
||||
"murmur2",
|
||||
"paste",
|
||||
@@ -4715,8 +4576,6 @@ dependencies = [
|
||||
"totp-rs",
|
||||
"tracing",
|
||||
"tracing-actix-web",
|
||||
"tracing-ecs",
|
||||
"tracing-subscriber",
|
||||
"url",
|
||||
"urlencoding",
|
||||
"utoipa",
|
||||
@@ -5030,12 +4889,6 @@ version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
|
||||
|
||||
[[package]]
|
||||
name = "matchit"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
|
||||
|
||||
[[package]]
|
||||
name = "maxminddb"
|
||||
version = "0.26.0"
|
||||
@@ -5230,6 +5083,9 @@ dependencies = [
|
||||
"dotenvy",
|
||||
"eyre",
|
||||
"serde",
|
||||
"tracing",
|
||||
"tracing-ecs",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6743,15 +6599,6 @@ dependencies = [
|
||||
"syn 2.0.106",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-types"
|
||||
version = "0.13.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16"
|
||||
dependencies = [
|
||||
"prost",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "protobuf"
|
||||
version = "3.7.2"
|
||||
@@ -7332,7 +7179,7 @@ dependencies = [
|
||||
"tokio-native-tls",
|
||||
"tokio-rustls 0.26.4",
|
||||
"tokio-util",
|
||||
"tower 0.5.2",
|
||||
"tower",
|
||||
"tower-http",
|
||||
"tower-service",
|
||||
"url",
|
||||
@@ -10029,36 +9876,6 @@ version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2"
|
||||
|
||||
[[package]]
|
||||
name = "tonic"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52"
|
||||
dependencies = [
|
||||
"async-stream",
|
||||
"async-trait",
|
||||
"axum",
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"h2 0.4.12",
|
||||
"http 1.3.1",
|
||||
"http-body 1.0.1",
|
||||
"http-body-util",
|
||||
"hyper 1.7.0",
|
||||
"hyper-timeout",
|
||||
"hyper-util",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"prost",
|
||||
"socket2 0.5.10",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tower 0.4.13",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "totp-rs"
|
||||
version = "5.7.0"
|
||||
@@ -10073,26 +9890,6 @@ dependencies = [
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"indexmap 1.9.3",
|
||||
"pin-project",
|
||||
"pin-project-lite",
|
||||
"rand 0.8.5",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower"
|
||||
version = "0.5.2"
|
||||
@@ -10121,7 +9918,7 @@ dependencies = [
|
||||
"http-body 1.0.1",
|
||||
"iri-string",
|
||||
"pin-project-lite",
|
||||
"tower 0.5.2",
|
||||
"tower",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
@@ -55,7 +55,6 @@ clap = "4.5.48"
|
||||
clickhouse = "0.14.0"
|
||||
color-eyre = "0.6.5"
|
||||
color-thief = "0.2.2"
|
||||
console-subscriber = "0.4.1"
|
||||
const_format = "0.2.34"
|
||||
daedalus = { path = "packages/daedalus" }
|
||||
dashmap = "6.1.0"
|
||||
|
||||
@@ -12,6 +12,7 @@ path = "src/main.rs"
|
||||
[dependencies]
|
||||
actix-cors = { workspace = true }
|
||||
actix-files = { workspace = true }
|
||||
actix-http = { workspace = true, optional = true }
|
||||
actix-multipart = { workspace = true }
|
||||
actix-rt = { workspace = true }
|
||||
actix-web = { workspace = true }
|
||||
@@ -36,7 +37,6 @@ clap = { workspace = true, features = ["derive"] }
|
||||
clickhouse = { workspace = true, features = ["time", "uuid"] }
|
||||
color-eyre = { workspace = true }
|
||||
color-thief = { workspace = true }
|
||||
console-subscriber = { workspace = true }
|
||||
const_format = { workspace = true }
|
||||
dashmap = { workspace = true }
|
||||
deadpool-redis.workspace = true
|
||||
@@ -71,6 +71,7 @@ json-patch = { workspace = true }
|
||||
lettre = { workspace = true }
|
||||
meilisearch-sdk = { workspace = true, features = ["reqwest"] }
|
||||
modrinth-maxmind = { workspace = true }
|
||||
modrinth-util = { workspace = true }
|
||||
muralpay = { workspace = true, features = ["utoipa"] }
|
||||
murmur2 = { workspace = true }
|
||||
paste = { workspace = true }
|
||||
@@ -119,8 +120,6 @@ tokio-stream = { workspace = true }
|
||||
totp-rs = { workspace = true, features = ["gen_secret"] }
|
||||
tracing = { workspace = true }
|
||||
tracing-actix-web = { workspace = true }
|
||||
tracing-ecs = { workspace = true }
|
||||
tracing-subscriber = { workspace = true }
|
||||
url = { workspace = true }
|
||||
urlencoding = { workspace = true }
|
||||
utoipa = { workspace = true }
|
||||
@@ -135,7 +134,7 @@ zip = { workspace = true }
|
||||
zxcvbn = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
actix-http = { workspace = true }
|
||||
labrinth = { path = ".", features = ["test"] }
|
||||
|
||||
[build-dependencies]
|
||||
chrono = { workspace = true }
|
||||
@@ -150,5 +149,8 @@ tikv-jemallocator = { workspace = true, features = [
|
||||
"unprefixed_malloc_on_supported_platforms",
|
||||
] }
|
||||
|
||||
[features]
|
||||
test = ["dep:actix-http"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
@@ -160,7 +160,7 @@ impl NotificationBuilder {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn insert_many_deliveries(
|
||||
pub async fn insert_many_deliveries(
|
||||
transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
|
||||
redis: &RedisPool,
|
||||
notification_ids: &[i64],
|
||||
|
||||
@@ -37,10 +37,12 @@ pub mod routes;
|
||||
pub mod scheduler;
|
||||
pub mod search;
|
||||
pub mod sync;
|
||||
pub mod test;
|
||||
pub mod util;
|
||||
pub mod validate;
|
||||
|
||||
#[cfg(feature = "test")]
|
||||
pub mod test;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Pepper {
|
||||
pub pepper: String,
|
||||
|
||||
@@ -17,15 +17,9 @@ use labrinth::util::ratelimit::rate_limit_middleware;
|
||||
use labrinth::utoipa_app_config;
|
||||
use labrinth::{check_env_vars, clickhouse, database, file_hosting};
|
||||
use std::ffi::CStr;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use tracing::level_filters::LevelFilter;
|
||||
use tracing::{Instrument, error, info, info_span};
|
||||
use tracing_actix_web::TracingLogger;
|
||||
use tracing_ecs::ECSLayerBuilder;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
use tracing_subscriber::layer::SubscriberExt;
|
||||
use tracing_subscriber::util::SubscriberInitExt;
|
||||
use utoipa::OpenApi;
|
||||
use utoipa_actix_web::AppExt;
|
||||
use utoipa_swagger_ui::SwaggerUi;
|
||||
@@ -59,59 +53,13 @@ struct Args {
|
||||
run_background_task: Option<BackgroundTask>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq)]
|
||||
enum OutputFormat {
|
||||
#[default]
|
||||
Human,
|
||||
Json,
|
||||
}
|
||||
|
||||
impl FromStr for OutputFormat {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"human" => Ok(Self::Human),
|
||||
"json" => Ok(Self::Json),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_rt::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
let args = Args::parse();
|
||||
|
||||
color_eyre::install().expect("failed to install `color-eyre`");
|
||||
dotenvy::dotenv().ok();
|
||||
let console_layer = console_subscriber::spawn();
|
||||
let env_filter = EnvFilter::builder()
|
||||
.with_default_directive(LevelFilter::INFO.into())
|
||||
.from_env_lossy();
|
||||
|
||||
let output_format =
|
||||
dotenvy::var("LABRINTH_FORMAT").map_or(OutputFormat::Human, |format| {
|
||||
format
|
||||
.parse::<OutputFormat>()
|
||||
.unwrap_or_else(|_| panic!("invalid output format '{format}'"))
|
||||
});
|
||||
|
||||
match output_format {
|
||||
OutputFormat::Human => {
|
||||
tracing_subscriber::registry()
|
||||
.with(console_layer)
|
||||
.with(env_filter)
|
||||
.with(tracing_subscriber::fmt::layer())
|
||||
.init();
|
||||
}
|
||||
OutputFormat::Json => {
|
||||
tracing_subscriber::registry()
|
||||
.with(console_layer)
|
||||
.with(env_filter)
|
||||
.with(ECSLayerBuilder::default().stdout())
|
||||
.init();
|
||||
}
|
||||
}
|
||||
modrinth_util::log::init().expect("failed to initialize logging");
|
||||
|
||||
if check_env_vars() {
|
||||
error!("Some environment variables are missing!");
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::common::{api_v2::ApiV2, api_v3::ApiV3, dummy_data::TestFile};
|
||||
use actix_web::dev::ServiceResponse;
|
||||
use async_trait::async_trait;
|
||||
use labrinth::models::ids::ProjectId;
|
||||
use labrinth::models::{
|
||||
use crate::models::ids::ProjectId;
|
||||
use crate::models::{
|
||||
projects::VersionType,
|
||||
teams::{OrganizationPermissions, ProjectPermissions},
|
||||
};
|
||||
use crate::test::{api_v2::ApiV2, api_v3::ApiV3, dummy_data::TestFile};
|
||||
use actix_web::dev::ServiceResponse;
|
||||
use async_trait::async_trait;
|
||||
|
||||
use super::{
|
||||
Api, ApiProject, ApiTags, ApiTeams, ApiUser, ApiVersion,
|
||||
@@ -81,7 +81,7 @@ delegate_api_variant!(
|
||||
[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>],
|
||||
[create_report, ServiceResponse, report_type: &str, id: &str, item_type: crate::test::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>],
|
||||
@@ -100,9 +100,9 @@ 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_loaders_deserialized_common, Vec<crate::test::api_common::models::CommonLoaderData>,],
|
||||
[get_categories, ServiceResponse,],
|
||||
[get_categories_deserialized_common, Vec<crate::common::api_common::models::CommonCategoryData>,],
|
||||
[get_categories_deserialized_common, Vec<crate::test::api_common::models::CommonCategoryData>,],
|
||||
}
|
||||
);
|
||||
|
||||
@@ -110,18 +110,18 @@ 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_team_members_deserialized_common, Vec<crate::test::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_project_members_deserialized_common, Vec<crate::test::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>],
|
||||
[get_organization_members_deserialized_common, Vec<crate::test::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_user_notifications_deserialized_common, Vec<crate::test::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>],
|
||||
@@ -6,16 +6,16 @@ use self::models::{
|
||||
};
|
||||
use self::request_data::{ImageData, ProjectCreationRequestData};
|
||||
use super::dummy_data::TestFile;
|
||||
use actix_web::dev::ServiceResponse;
|
||||
use async_trait::async_trait;
|
||||
use labrinth::models::ids::ProjectId;
|
||||
use labrinth::{
|
||||
use crate::models::ids::ProjectId;
|
||||
use crate::{
|
||||
LabrinthConfig,
|
||||
models::{
|
||||
projects::VersionType,
|
||||
teams::{OrganizationPermissions, ProjectPermissions},
|
||||
},
|
||||
};
|
||||
use actix_web::dev::ServiceResponse;
|
||||
use async_trait::async_trait;
|
||||
|
||||
pub mod generic;
|
||||
pub mod models;
|
||||
@@ -1,10 +1,8 @@
|
||||
use ariadne::ids::UserId;
|
||||
use chrono::{DateTime, Utc};
|
||||
use labrinth::models::ids::{
|
||||
use crate::models::ids::{
|
||||
ImageId, NotificationId, OrganizationId, ProjectId, ReportId, TeamId,
|
||||
ThreadId, ThreadMessageId, VersionId,
|
||||
};
|
||||
use labrinth::{
|
||||
use crate::{
|
||||
auth::AuthProvider,
|
||||
models::{
|
||||
projects::{
|
||||
@@ -16,6 +14,8 @@ use labrinth::{
|
||||
users::{Badges, Role, User, UserPayoutData},
|
||||
},
|
||||
};
|
||||
use ariadne::ids::UserId;
|
||||
use chrono::{DateTime, Utc};
|
||||
use rust_decimal::Decimal;
|
||||
use serde::Deserialize;
|
||||
// Fields shared by every version of the API.
|
||||
@@ -1,9 +1,9 @@
|
||||
// The structures for project/version creation.
|
||||
// These are created differently, but are essentially the same between versions.
|
||||
|
||||
use labrinth::util::actix::MultipartSegment;
|
||||
use crate::util::actix::MultipartSegment;
|
||||
|
||||
use crate::common::dummy_data::TestFile;
|
||||
use crate::test::dummy_data::TestFile;
|
||||
|
||||
pub struct ProjectCreationRequestData {
|
||||
pub slug: String,
|
||||
@@ -2,9 +2,9 @@ use super::{
|
||||
api_common::{Api, ApiBuildable},
|
||||
environment::LocalService,
|
||||
};
|
||||
use crate::LabrinthConfig;
|
||||
use actix_web::{App, dev::ServiceResponse, test};
|
||||
use async_trait::async_trait;
|
||||
use labrinth::LabrinthConfig;
|
||||
use std::rc::Rc;
|
||||
use utoipa_actix_web::AppExt;
|
||||
|
||||
@@ -26,12 +26,10 @@ impl ApiBuildable for ApiV2 {
|
||||
let app = App::new()
|
||||
.into_utoipa_app()
|
||||
.configure(|cfg| {
|
||||
labrinth::utoipa_app_config(cfg, labrinth_config.clone())
|
||||
crate::utoipa_app_config(cfg, labrinth_config.clone())
|
||||
})
|
||||
.into_app()
|
||||
.configure(|cfg| {
|
||||
labrinth::app_config(cfg, labrinth_config.clone())
|
||||
});
|
||||
.configure(|cfg| crate::app_config(cfg, labrinth_config.clone()));
|
||||
let test_app: Rc<dyn LocalService> =
|
||||
Rc::new(test::init_service(app).await);
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
use std::{collections::HashMap, fmt::Write};
|
||||
|
||||
use crate::{
|
||||
assert_status,
|
||||
common::{
|
||||
api_common::{
|
||||
Api, ApiProject, AppendsOptionalPat,
|
||||
models::{CommonItemType, CommonProject, CommonVersion},
|
||||
request_data::{ImageData, ProjectCreationRequestData},
|
||||
},
|
||||
dummy_data::TestFile,
|
||||
use crate::test::asserts::assert_status;
|
||||
use crate::test::{
|
||||
api_common::{
|
||||
Api, ApiProject, AppendsOptionalPat,
|
||||
models::{CommonItemType, CommonProject, CommonVersion},
|
||||
request_data::{ImageData, ProjectCreationRequestData},
|
||||
},
|
||||
dummy_data::TestFile,
|
||||
};
|
||||
use crate::{
|
||||
models::v2::{projects::LegacyProject, search::LegacySearchResults},
|
||||
util::actix::AppendsMultipart,
|
||||
};
|
||||
use actix_http::StatusCode;
|
||||
use actix_web::{
|
||||
@@ -18,13 +20,9 @@ use actix_web::{
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use bytes::Bytes;
|
||||
use labrinth::{
|
||||
models::v2::{projects::LegacyProject, search::LegacySearchResults},
|
||||
util::actix::AppendsMultipart,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
use crate::common::database::MOD_USER_PAT;
|
||||
use crate::test::database::MOD_USER_PAT;
|
||||
|
||||
use super::{
|
||||
ApiV2,
|
||||
@@ -1,13 +1,13 @@
|
||||
use serde_json::json;
|
||||
|
||||
use crate::common::{
|
||||
use crate::models::ids::ProjectId;
|
||||
use crate::test::{
|
||||
api_common::request_data::{
|
||||
ProjectCreationRequestData, VersionCreationRequestData,
|
||||
},
|
||||
dummy_data::TestFile,
|
||||
};
|
||||
use labrinth::models::ids::ProjectId;
|
||||
use labrinth::util::actix::{MultipartSegment, MultipartSegmentData};
|
||||
use crate::util::actix::{MultipartSegment, MultipartSegmentData};
|
||||
|
||||
pub fn get_public_project_creation_data(
|
||||
slug: &str,
|
||||
@@ -1,22 +1,20 @@
|
||||
use crate::routes::v2::tags::{
|
||||
CategoryData, DonationPlatformQueryData, GameVersionQueryData, LoaderData,
|
||||
};
|
||||
use actix_http::StatusCode;
|
||||
use actix_web::{
|
||||
dev::ServiceResponse,
|
||||
test::{self, TestRequest},
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use labrinth::routes::v2::tags::{
|
||||
CategoryData, DonationPlatformQueryData, GameVersionQueryData, LoaderData,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
assert_status,
|
||||
common::{
|
||||
api_common::{
|
||||
Api, ApiTags, AppendsOptionalPat,
|
||||
models::{CommonCategoryData, CommonLoaderData},
|
||||
},
|
||||
database::ADMIN_USER_PAT,
|
||||
use crate::test::asserts::assert_status;
|
||||
use crate::test::{
|
||||
api_common::{
|
||||
Api, ApiTags, AppendsOptionalPat,
|
||||
models::{CommonCategoryData, CommonLoaderData},
|
||||
},
|
||||
database::ADMIN_USER_PAT,
|
||||
};
|
||||
|
||||
use super::ApiV2;
|
||||
@@ -1,19 +1,17 @@
|
||||
use actix_http::StatusCode;
|
||||
use actix_web::{dev::ServiceResponse, test};
|
||||
use async_trait::async_trait;
|
||||
use labrinth::models::{
|
||||
use crate::models::{
|
||||
teams::{OrganizationPermissions, ProjectPermissions},
|
||||
v2::{notifications::LegacyNotification, teams::LegacyTeamMember},
|
||||
};
|
||||
use actix_http::StatusCode;
|
||||
use actix_web::{dev::ServiceResponse, test};
|
||||
use async_trait::async_trait;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{
|
||||
assert_status,
|
||||
common::api_common::{
|
||||
Api, ApiTeams, AppendsOptionalPat,
|
||||
models::{CommonNotification, CommonTeamMember},
|
||||
},
|
||||
use crate::test::api_common::{
|
||||
Api, ApiTeams, AppendsOptionalPat,
|
||||
models::{CommonNotification, CommonTeamMember},
|
||||
};
|
||||
use crate::test::asserts::assert_status;
|
||||
|
||||
use super::ApiV2;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::ApiV2;
|
||||
use crate::common::api_common::{Api, ApiUser, AppendsOptionalPat};
|
||||
use crate::test::api_common::{Api, ApiUser, AppendsOptionalPat};
|
||||
use actix_web::{dev::ServiceResponse, test};
|
||||
use async_trait::async_trait;
|
||||
|
||||
@@ -5,14 +5,16 @@ use super::{
|
||||
ApiV2,
|
||||
request_data::{self, get_public_version_creation_data},
|
||||
};
|
||||
use crate::models::ids::ProjectId;
|
||||
use crate::test::asserts::assert_status;
|
||||
use crate::test::{
|
||||
api_common::{Api, ApiVersion, AppendsOptionalPat, models::CommonVersion},
|
||||
dummy_data::TestFile,
|
||||
};
|
||||
use crate::{
|
||||
assert_status,
|
||||
common::{
|
||||
api_common::{
|
||||
Api, ApiVersion, AppendsOptionalPat, models::CommonVersion,
|
||||
},
|
||||
dummy_data::TestFile,
|
||||
},
|
||||
models::{projects::VersionType, v2::projects::LegacyVersion},
|
||||
routes::v2::version_file::FileUpdateData,
|
||||
util::actix::AppendsMultipart,
|
||||
};
|
||||
use actix_http::StatusCode;
|
||||
use actix_web::{
|
||||
@@ -20,12 +22,6 @@ use actix_web::{
|
||||
test::{self, TestRequest},
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use labrinth::models::ids::ProjectId;
|
||||
use labrinth::{
|
||||
models::{projects::VersionType, v2::projects::LegacyVersion},
|
||||
routes::v2::version_file::FileUpdateData,
|
||||
util::actix::AppendsMultipart,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub fn url_encode_json_serialized_vec(elements: &[String]) -> String {
|
||||
@@ -1,16 +1,16 @@
|
||||
use crate::models::{collections::Collection, v3::projects::Project};
|
||||
use actix_http::StatusCode;
|
||||
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::{
|
||||
assert_status,
|
||||
common::api_common::{Api, AppendsOptionalPat, request_data::ImageData},
|
||||
use crate::test::api_common::{
|
||||
Api, AppendsOptionalPat, request_data::ImageData,
|
||||
};
|
||||
use crate::test::asserts::assert_status;
|
||||
|
||||
use super::ApiV3;
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
use crate::models::v3::user_limits::UserLimits;
|
||||
use actix_http::StatusCode;
|
||||
use actix_web::test;
|
||||
use labrinth::models::v3::user_limits::UserLimits;
|
||||
|
||||
use crate::{
|
||||
assert_status,
|
||||
common::{
|
||||
api_common::{Api, AppendsOptionalPat},
|
||||
api_v3::ApiV3,
|
||||
},
|
||||
use crate::test::asserts::assert_status;
|
||||
use crate::test::{
|
||||
api_common::{Api, AppendsOptionalPat},
|
||||
api_v3::ApiV3,
|
||||
};
|
||||
|
||||
impl ApiV3 {
|
||||
@@ -2,9 +2,9 @@ use super::{
|
||||
api_common::{Api, ApiBuildable},
|
||||
environment::LocalService,
|
||||
};
|
||||
use crate::LabrinthConfig;
|
||||
use actix_web::{App, dev::ServiceResponse, test};
|
||||
use async_trait::async_trait;
|
||||
use labrinth::LabrinthConfig;
|
||||
use std::rc::Rc;
|
||||
use utoipa_actix_web::AppExt;
|
||||
|
||||
@@ -31,12 +31,10 @@ impl ApiBuildable for ApiV3 {
|
||||
let app = App::new()
|
||||
.into_utoipa_app()
|
||||
.configure(|cfg| {
|
||||
labrinth::utoipa_app_config(cfg, labrinth_config.clone())
|
||||
crate::utoipa_app_config(cfg, labrinth_config.clone())
|
||||
})
|
||||
.into_app()
|
||||
.configure(|cfg| {
|
||||
labrinth::app_config(cfg, labrinth_config.clone())
|
||||
});
|
||||
.configure(|cfg| crate::app_config(cfg, labrinth_config.clone()));
|
||||
let test_app: Rc<dyn LocalService> =
|
||||
Rc::new(test::init_service(app).await);
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::auth::oauth::{
|
||||
OAuthClientAccessRequest, RespondToOAuthClientScopes, TokenRequest,
|
||||
TokenResponse,
|
||||
};
|
||||
use actix_http::StatusCode;
|
||||
use actix_web::http::header::{AUTHORIZATION, LOCATION};
|
||||
use actix_web::{
|
||||
dev::ServiceResponse,
|
||||
test::{self, TestRequest},
|
||||
};
|
||||
use labrinth::auth::oauth::{
|
||||
OAuthClientAccessRequest, RespondToOAuthClientScopes, TokenRequest,
|
||||
TokenResponse,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
assert_status,
|
||||
common::api_common::{Api, AppendsOptionalPat},
|
||||
};
|
||||
use crate::test::api_common::{Api, AppendsOptionalPat};
|
||||
use crate::test::asserts::assert_status;
|
||||
|
||||
use super::ApiV3;
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
use actix_http::StatusCode;
|
||||
use actix_web::{
|
||||
dev::ServiceResponse,
|
||||
test::{self, TestRequest},
|
||||
};
|
||||
use labrinth::{
|
||||
use crate::{
|
||||
models::{
|
||||
oauth_clients::{OAuthClient, OAuthClientAuthorization},
|
||||
pats::Scopes,
|
||||
},
|
||||
routes::v3::oauth_clients::OAuthClientEdit,
|
||||
};
|
||||
use actix_http::StatusCode;
|
||||
use actix_web::{
|
||||
dev::ServiceResponse,
|
||||
test::{self, TestRequest},
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{
|
||||
assert_status,
|
||||
common::api_common::{Api, AppendsOptionalPat},
|
||||
};
|
||||
use crate::test::api_common::{Api, AppendsOptionalPat};
|
||||
use crate::test::asserts::assert_status;
|
||||
|
||||
use super::ApiV3;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use crate::{
|
||||
assert_status,
|
||||
common::api_common::{Api, AppendsOptionalPat, request_data::ImageData},
|
||||
use crate::models::{organizations::Organization, v3::projects::Project};
|
||||
use crate::test::api_common::{
|
||||
Api, AppendsOptionalPat, request_data::ImageData,
|
||||
};
|
||||
use crate::test::asserts::assert_status;
|
||||
use actix_http::StatusCode;
|
||||
use actix_web::{
|
||||
dev::ServiceResponse,
|
||||
@@ -9,7 +10,6 @@ use actix_web::{
|
||||
};
|
||||
use ariadne::ids::UserId;
|
||||
use bytes::Bytes;
|
||||
use labrinth::models::{organizations::Organization, v3::projects::Project};
|
||||
use serde_json::json;
|
||||
|
||||
use super::ApiV3;
|
||||
@@ -1,5 +1,10 @@
|
||||
use std::{collections::HashMap, fmt::Write};
|
||||
|
||||
use crate::{
|
||||
models::{organizations::Organization, projects::Project},
|
||||
search::SearchResults,
|
||||
util::actix::AppendsMultipart,
|
||||
};
|
||||
use actix_http::StatusCode;
|
||||
use actix_web::{
|
||||
dev::ServiceResponse,
|
||||
@@ -8,25 +13,18 @@ use actix_web::{
|
||||
use async_trait::async_trait;
|
||||
use bytes::Bytes;
|
||||
use chrono::{DateTime, Utc};
|
||||
use labrinth::{
|
||||
models::{organizations::Organization, projects::Project},
|
||||
search::SearchResults,
|
||||
util::actix::AppendsMultipart,
|
||||
};
|
||||
use rust_decimal::Decimal;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{
|
||||
assert_status,
|
||||
common::{
|
||||
api_common::{
|
||||
Api, ApiProject, AppendsOptionalPat,
|
||||
models::{CommonItemType, CommonProject, CommonVersion},
|
||||
request_data::{ImageData, ProjectCreationRequestData},
|
||||
},
|
||||
database::MOD_USER_PAT,
|
||||
dummy_data::TestFile,
|
||||
use crate::test::asserts::assert_status;
|
||||
use crate::test::{
|
||||
api_common::{
|
||||
Api, ApiProject, AppendsOptionalPat,
|
||||
models::{CommonItemType, CommonProject, CommonVersion},
|
||||
request_data::{ImageData, ProjectCreationRequestData},
|
||||
},
|
||||
database::MOD_USER_PAT,
|
||||
dummy_data::TestFile,
|
||||
};
|
||||
|
||||
use super::{
|
||||
@@ -1,13 +1,13 @@
|
||||
use serde_json::json;
|
||||
|
||||
use crate::common::{
|
||||
use crate::models::ids::ProjectId;
|
||||
use crate::test::{
|
||||
api_common::request_data::{
|
||||
ProjectCreationRequestData, VersionCreationRequestData,
|
||||
},
|
||||
dummy_data::TestFile,
|
||||
};
|
||||
use labrinth::models::ids::ProjectId;
|
||||
use labrinth::util::actix::{MultipartSegment, MultipartSegmentData};
|
||||
use crate::util::actix::{MultipartSegment, MultipartSegmentData};
|
||||
|
||||
pub fn get_public_project_creation_data(
|
||||
slug: &str,
|
||||
@@ -1,24 +1,22 @@
|
||||
use crate::routes::v3::tags::{GameData, LoaderData};
|
||||
use crate::{
|
||||
database::models::loader_fields::LoaderFieldEnumValue,
|
||||
routes::v3::tags::CategoryData,
|
||||
};
|
||||
use actix_http::StatusCode;
|
||||
use actix_web::{
|
||||
dev::ServiceResponse,
|
||||
test::{self, TestRequest},
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use labrinth::routes::v3::tags::{GameData, LoaderData};
|
||||
use labrinth::{
|
||||
database::models::loader_fields::LoaderFieldEnumValue,
|
||||
routes::v3::tags::CategoryData,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
assert_status,
|
||||
common::{
|
||||
api_common::{
|
||||
Api, ApiTags, AppendsOptionalPat,
|
||||
models::{CommonCategoryData, CommonLoaderData},
|
||||
},
|
||||
database::ADMIN_USER_PAT,
|
||||
use crate::test::asserts::assert_status;
|
||||
use crate::test::{
|
||||
api_common::{
|
||||
Api, ApiTags, AppendsOptionalPat,
|
||||
models::{CommonCategoryData, CommonLoaderData},
|
||||
},
|
||||
database::ADMIN_USER_PAT,
|
||||
};
|
||||
|
||||
use super::ApiV3;
|
||||
@@ -1,19 +1,17 @@
|
||||
use actix_http::StatusCode;
|
||||
use actix_web::{dev::ServiceResponse, test};
|
||||
use async_trait::async_trait;
|
||||
use labrinth::models::{
|
||||
use crate::models::{
|
||||
notifications::Notification,
|
||||
teams::{OrganizationPermissions, ProjectPermissions, TeamMember},
|
||||
};
|
||||
use actix_http::StatusCode;
|
||||
use actix_web::{dev::ServiceResponse, test};
|
||||
use async_trait::async_trait;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{
|
||||
assert_status,
|
||||
common::api_common::{
|
||||
Api, ApiTeams, AppendsOptionalPat,
|
||||
models::{CommonNotification, CommonTeamMember},
|
||||
},
|
||||
use crate::test::api_common::{
|
||||
Api, ApiTeams, AppendsOptionalPat,
|
||||
models::{CommonNotification, CommonTeamMember},
|
||||
};
|
||||
use crate::test::asserts::assert_status;
|
||||
|
||||
use super::ApiV3;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use actix_web::{dev::ServiceResponse, test};
|
||||
use async_trait::async_trait;
|
||||
|
||||
use crate::common::api_common::{Api, ApiUser, AppendsOptionalPat};
|
||||
use crate::test::api_common::{Api, ApiUser, AppendsOptionalPat};
|
||||
|
||||
use super::ApiV3;
|
||||
|
||||
@@ -5,14 +5,16 @@ use super::{
|
||||
ApiV3,
|
||||
request_data::{self, get_public_version_creation_data},
|
||||
};
|
||||
use crate::models::ids::ProjectId;
|
||||
use crate::test::asserts::assert_status;
|
||||
use crate::test::{
|
||||
api_common::{Api, ApiVersion, AppendsOptionalPat, models::CommonVersion},
|
||||
dummy_data::TestFile,
|
||||
};
|
||||
use crate::{
|
||||
assert_status,
|
||||
common::{
|
||||
api_common::{
|
||||
Api, ApiVersion, AppendsOptionalPat, models::CommonVersion,
|
||||
},
|
||||
dummy_data::TestFile,
|
||||
},
|
||||
models::{projects::VersionType, v3::projects::Version},
|
||||
routes::v3::version_file::FileUpdateData,
|
||||
util::actix::AppendsMultipart,
|
||||
};
|
||||
use actix_http::StatusCode;
|
||||
use actix_web::{
|
||||
@@ -20,12 +22,6 @@ use actix_web::{
|
||||
test::{self, TestRequest},
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use labrinth::models::ids::ProjectId;
|
||||
use labrinth::{
|
||||
models::{projects::VersionType, v3::projects::Version},
|
||||
routes::v3::version_file::FileUpdateData,
|
||||
util::actix::AppendsMultipart,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub fn url_encode_json_serialized_vec(elements: &[String]) -> String {
|
||||
@@ -1,10 +1,9 @@
|
||||
use crate::common::get_json_val_str;
|
||||
use crate::models::v3::projects::Version;
|
||||
use crate::test::get_json_val_str;
|
||||
use itertools::Itertools;
|
||||
use labrinth::models::v3::projects::Version;
|
||||
|
||||
use super::api_common::models::CommonVersion;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! assert_status {
|
||||
($response:expr, $status:expr) => {
|
||||
assert_eq!(
|
||||
@@ -16,17 +15,7 @@ macro_rules! assert_status {
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! assert_any_status_except {
|
||||
($response:expr, $status:expr) => {
|
||||
assert_ne!(
|
||||
$response.status(),
|
||||
$status,
|
||||
"{:#?}",
|
||||
$response.response().body()
|
||||
);
|
||||
};
|
||||
}
|
||||
pub(crate) use assert_status;
|
||||
|
||||
pub fn assert_version_ids(versions: &[Version], expected_ids: Vec<String>) {
|
||||
let version_ids = versions
|
||||
@@ -1,11 +1,11 @@
|
||||
use labrinth::database::ReadOnlyPgPool;
|
||||
use labrinth::database::redis::RedisPool;
|
||||
use labrinth::search;
|
||||
use crate::database::redis::RedisPool;
|
||||
use crate::database::{MIGRATOR, ReadOnlyPgPool};
|
||||
use crate::search;
|
||||
use sqlx::{PgPool, postgres::PgPoolOptions};
|
||||
use std::time::Duration;
|
||||
use url::Url;
|
||||
|
||||
use crate::common::{dummy_data, environment::TestEnvironment};
|
||||
use crate::test::{dummy_data, environment::TestEnvironment};
|
||||
|
||||
use super::{api_v3::ApiV3, dummy_data::DUMMY_DATA_UPDATE};
|
||||
|
||||
@@ -40,7 +40,7 @@ pub struct TemporaryDatabase {
|
||||
pub pool: PgPool,
|
||||
pub ro_pool: ReadOnlyPgPool,
|
||||
pub redis_pool: RedisPool,
|
||||
pub search_config: labrinth::search::SearchConfig,
|
||||
pub search_config: crate::search::SearchConfig,
|
||||
pub database_name: String,
|
||||
}
|
||||
|
||||
@@ -82,8 +82,7 @@ impl TemporaryDatabase {
|
||||
println!("Running migrations on temporary database");
|
||||
|
||||
// Performs migrations
|
||||
let migrations = sqlx::migrate!("./migrations");
|
||||
migrations.run(&pool).await.expect("Migrations failed");
|
||||
MIGRATOR.run(&pool).await.expect("Migrations failed");
|
||||
|
||||
println!("Migrations complete");
|
||||
|
||||
@@ -182,8 +181,7 @@ impl TemporaryDatabase {
|
||||
}
|
||||
|
||||
// Run migrations on the template
|
||||
let migrations = sqlx::migrate!("./migrations");
|
||||
migrations.run(&pool).await.expect("Migrations failed");
|
||||
MIGRATOR.run(&pool).await.expect("Migrations failed");
|
||||
|
||||
if !dummy_data_exists {
|
||||
// Add dummy data
|
||||
@@ -1,17 +1,15 @@
|
||||
use std::io::{Cursor, Write};
|
||||
|
||||
use crate::{
|
||||
assert_status,
|
||||
common::{api_common::Api, api_v3, database::USER_USER_PAT},
|
||||
};
|
||||
use actix_http::StatusCode;
|
||||
use actix_web::test::{self, TestRequest};
|
||||
use labrinth::models::ids::ProjectId;
|
||||
use labrinth::models::{
|
||||
use crate::models::ids::ProjectId;
|
||||
use crate::models::{
|
||||
oauth_clients::OAuthClient,
|
||||
organizations::Organization,
|
||||
projects::{Project, Version},
|
||||
};
|
||||
use crate::test::asserts::assert_status;
|
||||
use crate::test::{api_common::Api, api_v3, database::USER_USER_PAT};
|
||||
use actix_http::StatusCode;
|
||||
use actix_web::test::{self, TestRequest};
|
||||
use serde_json::json;
|
||||
use zip::{CompressionMethod, ZipWriter, write::FileOptions};
|
||||
|
||||
@@ -289,7 +287,7 @@ pub async fn add_dummy_data(api: &ApiV3, db: TemporaryDatabase) -> DummyData {
|
||||
// Adds basic dummy data to the database directly with sql (user, pats)
|
||||
let pool = &db.pool.clone();
|
||||
|
||||
labrinth::test::db::add_dummy_data(pool).await.unwrap();
|
||||
crate::test::db::add_dummy_data(pool).await.unwrap();
|
||||
|
||||
let (alpha_project, alpha_version) = add_project_alpha(api).await;
|
||||
let (beta_project, beta_version) = add_project_beta(api).await;
|
||||
@@ -5,7 +5,8 @@ use super::{
|
||||
database::{FRIEND_USER_ID, TemporaryDatabase, USER_USER_PAT},
|
||||
dummy_data,
|
||||
};
|
||||
use crate::{assert_status, common::setup};
|
||||
use crate::test::asserts::assert_status;
|
||||
use crate::test::setup;
|
||||
use actix_http::StatusCode;
|
||||
use actix_web::dev::ServiceResponse;
|
||||
use futures::Future;
|
||||
@@ -1 +1,76 @@
|
||||
use crate::queue::email::EmailQueue;
|
||||
use crate::util::anrok;
|
||||
use crate::util::gotenberg::GotenbergClient;
|
||||
use crate::{LabrinthConfig, file_hosting};
|
||||
use crate::{check_env_vars, clickhouse};
|
||||
use modrinth_maxmind::MaxMind;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub mod api_common;
|
||||
pub mod api_v2;
|
||||
pub mod api_v3;
|
||||
pub mod asserts;
|
||||
pub mod database;
|
||||
pub mod db;
|
||||
pub mod dummy_data;
|
||||
pub mod environment;
|
||||
pub mod pats;
|
||||
pub mod permissions;
|
||||
pub mod scopes;
|
||||
pub mod search;
|
||||
|
||||
// Testing equivalent to 'setup' function, producing a LabrinthConfig
|
||||
// If making a test, you should probably use environment::TestEnvironment::build() (which calls this)
|
||||
pub async fn setup(db: &database::TemporaryDatabase) -> LabrinthConfig {
|
||||
println!("Setting up labrinth config");
|
||||
|
||||
dotenvy::dotenv().ok();
|
||||
|
||||
if check_env_vars() {
|
||||
println!("Some environment variables are missing!");
|
||||
}
|
||||
|
||||
let _ = rustls::crypto::aws_lc_rs::default_provider().install_default();
|
||||
|
||||
let pool = db.pool.clone();
|
||||
let ro_pool = db.ro_pool.clone();
|
||||
let redis_pool = db.redis_pool.clone();
|
||||
let search_config = db.search_config.clone();
|
||||
let file_host: Arc<dyn file_hosting::FileHost + Send + Sync> =
|
||||
Arc::new(file_hosting::MockHost::new());
|
||||
let mut clickhouse = clickhouse::init_client().await.unwrap();
|
||||
|
||||
let maxmind_reader = MaxMind::new().await;
|
||||
|
||||
let stripe_client =
|
||||
stripe::Client::new(dotenvy::var("STRIPE_API_KEY").unwrap());
|
||||
|
||||
let anrok_client = anrok::Client::from_env().unwrap();
|
||||
let email_queue =
|
||||
EmailQueue::init(pool.clone(), redis_pool.clone()).unwrap();
|
||||
let gotenberg_client =
|
||||
GotenbergClient::from_env().expect("Failed to create Gotenberg client");
|
||||
|
||||
crate::app_setup(
|
||||
pool.clone(),
|
||||
ro_pool.clone(),
|
||||
redis_pool.clone(),
|
||||
search_config,
|
||||
&mut clickhouse,
|
||||
file_host.clone(),
|
||||
maxmind_reader,
|
||||
stripe_client,
|
||||
anrok_client,
|
||||
email_queue,
|
||||
gotenberg_client,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_json_val_str(val: impl serde::Serialize) -> String {
|
||||
serde_json::to_value(val)
|
||||
.unwrap()
|
||||
.as_str()
|
||||
.unwrap()
|
||||
.to_string()
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use chrono::Utc;
|
||||
use labrinth::{
|
||||
use crate::{
|
||||
database::{self, models::generate_pat_id},
|
||||
models::pats::Scopes,
|
||||
};
|
||||
use chrono::Utc;
|
||||
|
||||
use super::database::TemporaryDatabase;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use crate::models::teams::{OrganizationPermissions, ProjectPermissions};
|
||||
use actix_http::StatusCode;
|
||||
use actix_web::{dev::ServiceResponse, test};
|
||||
use futures::Future;
|
||||
use itertools::Itertools;
|
||||
use labrinth::models::teams::{OrganizationPermissions, ProjectPermissions};
|
||||
use serde_json::json;
|
||||
|
||||
use crate::common::{
|
||||
use crate::test::{
|
||||
api_common::ApiTeams,
|
||||
database::{ADMIN_USER_PAT, generate_random_name},
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::models::pats::Scopes;
|
||||
use actix_web::{dev::ServiceResponse, test};
|
||||
use futures::Future;
|
||||
use labrinth::models::pats::Scopes;
|
||||
|
||||
use super::{
|
||||
api_common::Api, database::USER_USER_ID_PARSED,
|
||||
@@ -3,13 +3,11 @@ use std::{collections::HashMap, sync::Arc};
|
||||
use actix_http::StatusCode;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{
|
||||
assert_status,
|
||||
common::{
|
||||
api_common::{Api, ApiProject, ApiVersion},
|
||||
database::{FRIEND_USER_PAT, MOD_USER_PAT, USER_USER_PAT},
|
||||
dummy_data::{DUMMY_CATEGORIES, TestFile},
|
||||
},
|
||||
use crate::test::asserts::assert_status;
|
||||
use crate::test::{
|
||||
api_common::{Api, ApiProject, ApiVersion},
|
||||
database::{FRIEND_USER_PAT, MOD_USER_PAT, USER_USER_PAT},
|
||||
dummy_data::{DUMMY_CATEGORIES, TestFile},
|
||||
};
|
||||
|
||||
use super::{api_v3::ApiV3, environment::TestEnvironment};
|
||||
32
apps/labrinth/tests/common.rs
Normal file
32
apps/labrinth/tests/common.rs
Normal file
@@ -0,0 +1,32 @@
|
||||
//! Re-exports all [`labrinth::test`] items for compatibility.
|
||||
//!
|
||||
//! Previously, tests used `mod common` and `common::item` imports for testing.
|
||||
//! This has been moved into [`labrinth::test`] under a feature flag, and this
|
||||
//! module remains for backwards compatibility with tests which expect the
|
||||
//! `common` module.
|
||||
|
||||
pub use labrinth::test::*;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! assert_status {
|
||||
($response:expr, $status:expr) => {
|
||||
assert_eq!(
|
||||
$response.status(),
|
||||
$status,
|
||||
"{:#?}",
|
||||
$response.response().body()
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! assert_any_status_except {
|
||||
($response:expr, $status:expr) => {
|
||||
assert_ne!(
|
||||
$response.status(),
|
||||
$status,
|
||||
"{:#?}",
|
||||
$response.response().body()
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
use labrinth::queue::email::EmailQueue;
|
||||
use labrinth::util::anrok;
|
||||
use labrinth::util::gotenberg::GotenbergClient;
|
||||
use labrinth::{LabrinthConfig, file_hosting};
|
||||
use labrinth::{check_env_vars, clickhouse};
|
||||
use modrinth_maxmind::MaxMind;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub mod api_common;
|
||||
pub mod api_v2;
|
||||
pub mod api_v3;
|
||||
pub mod asserts;
|
||||
pub mod database;
|
||||
pub mod dummy_data;
|
||||
pub mod environment;
|
||||
pub mod pats;
|
||||
pub mod permissions;
|
||||
pub mod scopes;
|
||||
pub mod search;
|
||||
|
||||
// Testing equivalent to 'setup' function, producing a LabrinthConfig
|
||||
// If making a test, you should probably use environment::TestEnvironment::build() (which calls this)
|
||||
pub async fn setup(db: &database::TemporaryDatabase) -> LabrinthConfig {
|
||||
println!("Setting up labrinth config");
|
||||
|
||||
dotenvy::dotenv().ok();
|
||||
|
||||
if check_env_vars() {
|
||||
println!("Some environment variables are missing!");
|
||||
}
|
||||
|
||||
let _ = rustls::crypto::aws_lc_rs::default_provider().install_default();
|
||||
|
||||
let pool = db.pool.clone();
|
||||
let ro_pool = db.ro_pool.clone();
|
||||
let redis_pool = db.redis_pool.clone();
|
||||
let search_config = db.search_config.clone();
|
||||
let file_host: Arc<dyn file_hosting::FileHost + Send + Sync> =
|
||||
Arc::new(file_hosting::MockHost::new());
|
||||
let mut clickhouse = clickhouse::init_client().await.unwrap();
|
||||
|
||||
let maxmind_reader = MaxMind::new().await;
|
||||
|
||||
let stripe_client =
|
||||
stripe::Client::new(dotenvy::var("STRIPE_API_KEY").unwrap());
|
||||
|
||||
let anrok_client = anrok::Client::from_env().unwrap();
|
||||
let email_queue =
|
||||
EmailQueue::init(pool.clone(), redis_pool.clone()).unwrap();
|
||||
let gotenberg_client =
|
||||
GotenbergClient::from_env().expect("Failed to create Gotenberg client");
|
||||
|
||||
labrinth::app_setup(
|
||||
pool.clone(),
|
||||
ro_pool.clone(),
|
||||
redis_pool.clone(),
|
||||
search_config,
|
||||
&mut clickhouse,
|
||||
file_host.clone(),
|
||||
maxmind_reader,
|
||||
stripe_client,
|
||||
anrok_client,
|
||||
email_queue,
|
||||
gotenberg_client,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_json_val_str(val: impl serde::Serialize) -> String {
|
||||
serde_json::to_value(val)
|
||||
.unwrap()
|
||||
.as_str()
|
||||
.unwrap()
|
||||
.to_string()
|
||||
}
|
||||
@@ -1,15 +1,16 @@
|
||||
use crate::assert_status;
|
||||
use crate::common::api_common::ApiProject;
|
||||
|
||||
use actix_http::StatusCode;
|
||||
use actix_web::test;
|
||||
use bytes::Bytes;
|
||||
|
||||
use crate::assert_status;
|
||||
use crate::common::database::USER_USER_PAT;
|
||||
use crate::common::{
|
||||
api_v2::ApiV2,
|
||||
environment::{TestEnvironment, with_test_environment},
|
||||
};
|
||||
|
||||
#[actix_rt::test]
|
||||
pub async fn error_404_empty() {
|
||||
with_test_environment(
|
||||
|
||||
@@ -10,6 +10,9 @@ derive_more = { workspace = true, features = ["display", "error", "from"] }
|
||||
dotenvy = { workspace = true }
|
||||
eyre = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
tracing = { workspace = true }
|
||||
tracing-ecs = { workspace = true }
|
||||
tracing-subscriber = { workspace = true }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#![doc = include_str!("../README.md")]
|
||||
|
||||
mod error;
|
||||
pub mod log;
|
||||
|
||||
pub use error::*;
|
||||
|
||||
use eyre::{Result, eyre};
|
||||
|
||||
74
packages/modrinth-util/src/log.rs
Normal file
74
packages/modrinth-util/src/log.rs
Normal file
@@ -0,0 +1,74 @@
|
||||
//! Service logging utilities.
|
||||
|
||||
use std::str::FromStr;
|
||||
|
||||
use eyre::{Result, eyre};
|
||||
use tracing::level_filters::LevelFilter;
|
||||
use tracing_ecs::ECSLayerBuilder;
|
||||
use tracing_subscriber::{
|
||||
EnvFilter, layer::SubscriberExt, util::SubscriberInitExt,
|
||||
};
|
||||
|
||||
use crate::{Context, env_var};
|
||||
|
||||
/// How this service will output logs to the terminal output.
|
||||
///
|
||||
/// See [`init`].
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq)]
|
||||
enum OutputFormat {
|
||||
/// Human-readable format using [`tracing_subscriber::fmt::layer`].
|
||||
#[default]
|
||||
Human,
|
||||
/// Elastic Common Schema JSON output using [`ECSLayerBuilder`].
|
||||
Json,
|
||||
}
|
||||
|
||||
impl FromStr for OutputFormat {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"human" => Ok(Self::Human),
|
||||
"json" => Ok(Self::Json),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Key for the environment variable that determines the output format.
|
||||
pub const OUTPUT_FORMAT_ENV_VAR: &str = "MODRINTH_OUTPUT_FORMAT";
|
||||
|
||||
/// Initializes logging for Modrinth services.
|
||||
///
|
||||
/// This uses [`OUTPUT_FORMAT_ENV_VAR`] to determine the [`OutputFormat`] to
|
||||
/// use - see that type for details of each possible format.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Errors if logging could not be initialized.
|
||||
pub fn init() -> Result<()> {
|
||||
let output_format = match env_var(OUTPUT_FORMAT_ENV_VAR) {
|
||||
Ok(format) => format
|
||||
.parse::<OutputFormat>()
|
||||
.map_err(|_| eyre!("invalid output format '{format}'"))?,
|
||||
Err(_) => OutputFormat::Human,
|
||||
};
|
||||
|
||||
let env_filter = EnvFilter::builder()
|
||||
.with_default_directive(LevelFilter::INFO.into())
|
||||
.from_env_lossy();
|
||||
|
||||
let result = match output_format {
|
||||
OutputFormat::Human => tracing_subscriber::registry()
|
||||
.with(env_filter)
|
||||
.with(tracing_subscriber::fmt::layer())
|
||||
.try_init(),
|
||||
OutputFormat::Json => tracing_subscriber::registry()
|
||||
.with(env_filter)
|
||||
.with(ECSLayerBuilder::default().stdout())
|
||||
.try_init(),
|
||||
};
|
||||
result.wrap_err("failed to initialize tracing registry")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user