mirror of https://github.com/LemmyNet/lemmy.git
add tests
parent
388eb42b99
commit
98b5746472
|
@ -2578,6 +2578,7 @@ dependencies = [
|
||||||
"activitypub_federation",
|
"activitypub_federation",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"async-trait",
|
||||||
"chrono",
|
"chrono",
|
||||||
"encoding",
|
"encoding",
|
||||||
"enum-map",
|
"enum-map",
|
||||||
|
@ -2598,6 +2599,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_with",
|
"serde_with",
|
||||||
"serial_test",
|
"serial_test",
|
||||||
|
"task-local-extensions",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"ts-rs",
|
"ts-rs",
|
||||||
|
@ -2653,14 +2655,12 @@ dependencies = [
|
||||||
"moka",
|
"moka",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"reqwest-middleware",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_with",
|
"serde_with",
|
||||||
"serial_test",
|
"serial_test",
|
||||||
"stringreader",
|
"stringreader",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
"task-local-extensions",
|
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"url",
|
"url",
|
||||||
|
|
|
@ -63,6 +63,7 @@ once_cell = { workspace = true, optional = true }
|
||||||
actix-web = { workspace = true, optional = true }
|
actix-web = { workspace = true, optional = true }
|
||||||
enum-map = { workspace = true }
|
enum-map = { workspace = true }
|
||||||
urlencoding = { workspace = true }
|
urlencoding = { workspace = true }
|
||||||
|
async-trait = { workspace = true }
|
||||||
webpage = { version = "1.6", default-features = false, features = [
|
webpage = { version = "1.6", default-features = false, features = [
|
||||||
"serde",
|
"serde",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
|
@ -70,6 +71,7 @@ encoding = { version = "0.2.33", optional = true }
|
||||||
jsonwebtoken = { version = "8.3.0", optional = true }
|
jsonwebtoken = { version = "8.3.0", optional = true }
|
||||||
# necessary for wasmt compilation
|
# necessary for wasmt compilation
|
||||||
getrandom = { version = "0.2.10", features = ["js"] }
|
getrandom = { version = "0.2.10", features = ["js"] }
|
||||||
|
task-local-extensions = "0.1.4"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serial_test = { workspace = true }
|
serial_test = { workspace = true }
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
|
use crate::request::client_builder;
|
||||||
|
use activitypub_federation::config::{Data, FederationConfig};
|
||||||
|
use anyhow::anyhow;
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::secret::Secret,
|
source::secret::Secret,
|
||||||
utils::{ActualDbPool, DbPool},
|
utils::{build_db_pool_for_tests, ActualDbPool, DbPool},
|
||||||
};
|
};
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
rate_limit::RateLimitCell,
|
rate_limit::RateLimitCell,
|
||||||
settings::{structs::Settings, SETTINGS},
|
settings::{structs::Settings, SETTINGS},
|
||||||
};
|
};
|
||||||
use reqwest_middleware::ClientWithMiddleware;
|
use reqwest::{Request, Response};
|
||||||
|
use reqwest_middleware::{ClientBuilder, ClientWithMiddleware, Middleware, Next};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use task_local_extensions::Extensions;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct LemmyContext {
|
pub struct LemmyContext {
|
||||||
|
@ -49,4 +54,46 @@ impl LemmyContext {
|
||||||
pub fn rate_limit_cell(&self) -> &RateLimitCell {
|
pub fn rate_limit_cell(&self) -> &RateLimitCell {
|
||||||
&self.rate_limit_cell
|
&self.rate_limit_cell
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Initialize a context for use in tests, doesn't allow network requests.
|
||||||
|
///
|
||||||
|
/// Do not use this in production code.
|
||||||
|
pub async fn init_test_context() -> Data<LemmyContext> {
|
||||||
|
// call this to run migrations
|
||||||
|
let pool = build_db_pool_for_tests().await;
|
||||||
|
|
||||||
|
let client = client_builder(&SETTINGS).build().expect("build client");
|
||||||
|
|
||||||
|
let client = ClientBuilder::new(client).with(BlockedMiddleware).build();
|
||||||
|
let secret = Secret {
|
||||||
|
id: 0,
|
||||||
|
jwt_secret: String::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let rate_limit_cell = RateLimitCell::with_test_config();
|
||||||
|
|
||||||
|
let context = LemmyContext::create(pool, client, secret, rate_limit_cell.clone());
|
||||||
|
let config = FederationConfig::builder()
|
||||||
|
.domain(context.settings().hostname.clone())
|
||||||
|
.app_data(context)
|
||||||
|
.build()
|
||||||
|
.await
|
||||||
|
.expect("build federation config");
|
||||||
|
config.to_request_data()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct BlockedMiddleware;
|
||||||
|
|
||||||
|
/// A reqwest middleware which blocks all requests
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl Middleware for BlockedMiddleware {
|
||||||
|
async fn handle(
|
||||||
|
&self,
|
||||||
|
_req: Request,
|
||||||
|
_extensions: &mut Extensions,
|
||||||
|
_next: Next<'_>,
|
||||||
|
) -> reqwest_middleware::Result<Response> {
|
||||||
|
Err(anyhow!("Network requests not allowed").into())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ use lemmy_db_schema::{
|
||||||
post::{Post, PostRead},
|
post::{Post, PostRead},
|
||||||
},
|
},
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
utils::{diesel_option_overwrite_to_url, DbPool},
|
utils::DbPool,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::{comment_view::CommentQuery, structs::LocalUserView};
|
use lemmy_db_views::{comment_view::CommentQuery, structs::LocalUserView};
|
||||||
use lemmy_db_views_actor::structs::{
|
use lemmy_db_views_actor::structs::{
|
||||||
|
@ -37,7 +37,7 @@ use lemmy_utils::{
|
||||||
error::{LemmyError, LemmyErrorExt, LemmyErrorType, LemmyResult},
|
error::{LemmyError, LemmyErrorExt, LemmyErrorType, LemmyResult},
|
||||||
location_info,
|
location_info,
|
||||||
rate_limit::{ActionType, BucketConfig},
|
rate_limit::{ActionType, BucketConfig},
|
||||||
settings::{structs::Settings, SETTINGS},
|
settings::structs::Settings,
|
||||||
utils::{
|
utils::{
|
||||||
markdown::markdown_rewrite_image_links,
|
markdown::markdown_rewrite_image_links,
|
||||||
slurs::{build_slur_regex, remove_slurs},
|
slurs::{build_slur_regex, remove_slurs},
|
||||||
|
@ -815,13 +815,13 @@ pub async fn process_markdown_opt(
|
||||||
|
|
||||||
pub async fn proxy_image_link(link: Url, context: &LemmyContext) -> LemmyResult<DbUrl> {
|
pub async fn proxy_image_link(link: Url, context: &LemmyContext) -> LemmyResult<DbUrl> {
|
||||||
// Dont rewrite links pointing to local domain.
|
// Dont rewrite links pointing to local domain.
|
||||||
if link.domain() == Some(&SETTINGS.hostname) {
|
if link.domain() == Some(&context.settings().hostname) {
|
||||||
return Ok(link.into());
|
return Ok(link.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let proxied = format!(
|
let proxied = format!(
|
||||||
"{}/api/v3/image_proxy?url={}",
|
"{}/api/v3/image_proxy?url={}",
|
||||||
SETTINGS.get_protocol_and_hostname(),
|
context.settings().get_protocol_and_hostname(),
|
||||||
encode(link.as_str())
|
encode(link.as_str())
|
||||||
);
|
);
|
||||||
RemoteImage::create(&mut context.pool(), vec![link]).await?;
|
RemoteImage::create(&mut context.pool(), vec![link]).await?;
|
||||||
|
@ -832,21 +832,30 @@ pub async fn proxy_image_link_opt_api(
|
||||||
link: &Option<String>,
|
link: &Option<String>,
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
) -> LemmyResult<Option<Option<DbUrl>>> {
|
) -> LemmyResult<Option<Option<DbUrl>>> {
|
||||||
let link = diesel_option_overwrite_to_url(link)?;
|
let link: Option<Option<DbUrl>> = match link.as_ref().map(String::as_str) {
|
||||||
if let Some(l) = link {
|
// An empty string is an erase
|
||||||
proxy_image_link_opt_apub(l.map(Into::into), context)
|
Some("") => Some(None),
|
||||||
|
Some(str_url) => Url::parse(str_url)
|
||||||
|
.map(|u| Some(Some(u.into())))
|
||||||
|
.with_lemmy_type(LemmyErrorType::InvalidUrl)?,
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
if let Some(Some(l)) = link {
|
||||||
|
proxy_image_link(l.into(), context)
|
||||||
.await
|
.await
|
||||||
.map(Some)
|
.map(Some)
|
||||||
|
.map(Some)
|
||||||
} else {
|
} else {
|
||||||
Ok(link)
|
Ok(link)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn proxy_image_link_opt_apub(
|
pub async fn proxy_image_link_opt_apub(
|
||||||
link: Option<Url>,
|
link: Option<Url>,
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
) -> LemmyResult<Option<DbUrl>> {
|
) -> LemmyResult<Option<DbUrl>> {
|
||||||
if let Some(l) = link {
|
if let Some(l) = link {
|
||||||
proxy_image_link(l.clone(), context).await.map(Some)
|
proxy_image_link(l, context).await.map(Some)
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
@ -857,8 +866,10 @@ mod tests {
|
||||||
#![allow(clippy::unwrap_used)]
|
#![allow(clippy::unwrap_used)]
|
||||||
#![allow(clippy::indexing_slicing)]
|
#![allow(clippy::indexing_slicing)]
|
||||||
|
|
||||||
|
use super::*;
|
||||||
use crate::utils::{honeypot_check, limit_expire_time, password_length_check};
|
use crate::utils::{honeypot_check, limit_expire_time, password_length_check};
|
||||||
use chrono::{Days, Utc};
|
use chrono::{Days, Utc};
|
||||||
|
use serial_test::serial;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
|
@ -897,4 +908,55 @@ mod tests {
|
||||||
None
|
None
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[serial]
|
||||||
|
async fn test_proxy_image_link() {
|
||||||
|
let context = LemmyContext::init_test_context().await;
|
||||||
|
|
||||||
|
// image from local domain is unchanged
|
||||||
|
let local_url = Url::parse("http://lemmy-alpha/image.png").unwrap();
|
||||||
|
let proxied = proxy_image_link(local_url.clone(), &context).await.unwrap();
|
||||||
|
assert_eq!(&local_url, proxied.inner());
|
||||||
|
|
||||||
|
// image from remote domain is proxied
|
||||||
|
let remote_image = Url::parse("http://lemmy-beta/image.png").unwrap();
|
||||||
|
let proxied = proxy_image_link(remote_image.clone(), &context)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
"https://lemmy-alpha/api/v3/image_proxy?url=http%3A%2F%2Flemmy-beta%2Fimage.png",
|
||||||
|
proxied.as_str()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
RemoteImage::validate(&mut context.pool(), remote_image.into())
|
||||||
|
.await
|
||||||
|
.is_ok()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[serial]
|
||||||
|
async fn test_diesel_option_overwrite_to_url() {
|
||||||
|
let context = LemmyContext::init_test_context().await;
|
||||||
|
|
||||||
|
assert!(matches!(
|
||||||
|
proxy_image_link_opt_api(&None, &context).await,
|
||||||
|
Ok(None)
|
||||||
|
));
|
||||||
|
assert!(matches!(
|
||||||
|
proxy_image_link_opt_api(&Some(String::new()), &context).await,
|
||||||
|
Ok(Some(None))
|
||||||
|
));
|
||||||
|
assert!(
|
||||||
|
proxy_image_link_opt_api(&Some("invalid_url".to_string()), &context)
|
||||||
|
.await
|
||||||
|
.is_err()
|
||||||
|
);
|
||||||
|
let example_url = "https://lemmy-alpha/image.png";
|
||||||
|
assert!(matches!(
|
||||||
|
proxy_image_link_opt_api(&Some(example_url.to_string()), &context).await,
|
||||||
|
Ok(Some(Some(url))) if url == Url::parse(example_url).unwrap().into()
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,12 @@ use lemmy_api_common::{
|
||||||
is_admin,
|
is_admin,
|
||||||
local_site_to_slur_regex,
|
local_site_to_slur_regex,
|
||||||
process_markdown_opt,
|
process_markdown_opt,
|
||||||
proxy_image_link_opt_api,
|
proxy_image_link,
|
||||||
EndpointType,
|
EndpointType,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
|
newtypes::DbUrl,
|
||||||
source::{
|
source::{
|
||||||
actor_language::{CommunityLanguage, SiteLanguage},
|
actor_language::{CommunityLanguage, SiteLanguage},
|
||||||
community::{
|
community::{
|
||||||
|
@ -38,6 +39,7 @@ use lemmy_utils::{
|
||||||
validation::{is_valid_actor_name, is_valid_body_field},
|
validation::{is_valid_actor_name, is_valid_body_field},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
pub async fn create_community(
|
pub async fn create_community(
|
||||||
|
@ -56,12 +58,8 @@ pub async fn create_community(
|
||||||
check_slurs(&data.name, &slur_regex)?;
|
check_slurs(&data.name, &slur_regex)?;
|
||||||
check_slurs(&data.title, &slur_regex)?;
|
check_slurs(&data.title, &slur_regex)?;
|
||||||
let description = process_markdown_opt(&data.description, &slur_regex, &context).await?;
|
let description = process_markdown_opt(&data.description, &slur_regex, &context).await?;
|
||||||
let icon = proxy_image_link_opt_api(&data.icon, &context)
|
let icon = proxy_image_link_create(&data.icon, &context).await?;
|
||||||
.await?
|
let banner = proxy_image_link_create(&data.banner, &context).await?;
|
||||||
.unwrap();
|
|
||||||
let banner = proxy_image_link_opt_api(&data.banner, &context)
|
|
||||||
.await?
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
is_valid_actor_name(&data.name, local_site.actor_name_max_length as usize)?;
|
is_valid_actor_name(&data.name, local_site.actor_name_max_length as usize)?;
|
||||||
is_valid_body_field(&data.description, false)?;
|
is_valid_body_field(&data.description, false)?;
|
||||||
|
@ -138,3 +136,19 @@ pub async fn create_community(
|
||||||
|
|
||||||
build_community_response(&context, local_user_view, community_id).await
|
build_community_response(&context, local_user_view, community_id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn proxy_image_link_create(
|
||||||
|
opt: &Option<String>,
|
||||||
|
context: &LemmyContext,
|
||||||
|
) -> Result<Option<DbUrl>, LemmyError> {
|
||||||
|
match opt.as_ref().map(String::as_str) {
|
||||||
|
// An empty string is nothing
|
||||||
|
Some("") => Ok(None),
|
||||||
|
Some(str_url) => {
|
||||||
|
let url = Url::parse(str_url).with_lemmy_type(LemmyErrorType::InvalidUrl)?;
|
||||||
|
let url = proxy_image_link(url, context).await?;
|
||||||
|
Ok(Some(url))
|
||||||
|
}
|
||||||
|
None => Ok(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -46,6 +46,4 @@ moka = { version = "0.11", features = ["future"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serial_test = { workspace = true }
|
serial_test = { workspace = true }
|
||||||
reqwest-middleware = { workspace = true }
|
|
||||||
task-local-extensions = "0.1.4"
|
|
||||||
assert-json-diff = "2.0.2"
|
assert-json-diff = "2.0.2"
|
||||||
|
|
|
@ -280,10 +280,7 @@ mod tests {
|
||||||
#![allow(clippy::unwrap_used)]
|
#![allow(clippy::unwrap_used)]
|
||||||
#![allow(clippy::indexing_slicing)]
|
#![allow(clippy::indexing_slicing)]
|
||||||
|
|
||||||
use crate::{
|
use crate::api::user_settings_backup::{export_settings, import_settings};
|
||||||
api::user_settings_backup::{export_settings, import_settings},
|
|
||||||
objects::tests::init_context,
|
|
||||||
};
|
|
||||||
use activitypub_federation::config::Data;
|
use activitypub_federation::config::Data;
|
||||||
use lemmy_api_common::context::LemmyContext;
|
use lemmy_api_common::context::LemmyContext;
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
|
@ -337,7 +334,7 @@ mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn test_settings_export_import() {
|
async fn test_settings_export_import() {
|
||||||
let context = init_context().await;
|
let context = LemmyContext::init_test_context().await;
|
||||||
|
|
||||||
let export_user = create_user("hanna".to_string(), Some("my bio".to_string()), &context).await;
|
let export_user = create_user("hanna".to_string(), Some("my bio".to_string()), &context).await;
|
||||||
|
|
||||||
|
@ -398,7 +395,7 @@ mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn disallow_large_backup() {
|
async fn disallow_large_backup() {
|
||||||
let context = init_context().await;
|
let context = LemmyContext::init_test_context().await;
|
||||||
|
|
||||||
let export_user = create_user("hanna".to_string(), Some("my bio".to_string()), &context).await;
|
let export_user = create_user("hanna".to_string(), Some("my bio".to_string()), &context).await;
|
||||||
|
|
||||||
|
|
|
@ -107,11 +107,7 @@ mod tests {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
objects::{
|
objects::{community::tests::parse_lemmy_community, person::tests::parse_lemmy_person},
|
||||||
community::tests::parse_lemmy_community,
|
|
||||||
person::tests::parse_lemmy_person,
|
|
||||||
tests::init_context,
|
|
||||||
},
|
|
||||||
protocol::tests::file_to_json_object,
|
protocol::tests::file_to_json_object,
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
|
@ -128,7 +124,7 @@ mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn test_parse_lemmy_community_moderators() {
|
async fn test_parse_lemmy_community_moderators() {
|
||||||
let context = init_context().await;
|
let context = LemmyContext::init_test_context().await;
|
||||||
let (new_mod, site) = parse_lemmy_person(&context).await;
|
let (new_mod, site) = parse_lemmy_person(&context).await;
|
||||||
let community = parse_lemmy_community(&context).await;
|
let community = parse_lemmy_community(&context).await;
|
||||||
let community_id = community.id;
|
let community_id = community.id;
|
||||||
|
|
|
@ -196,7 +196,6 @@ pub(crate) mod tests {
|
||||||
instance::ApubSite,
|
instance::ApubSite,
|
||||||
person::{tests::parse_lemmy_person, ApubPerson},
|
person::{tests::parse_lemmy_person, ApubPerson},
|
||||||
post::ApubPost,
|
post::ApubPost,
|
||||||
tests::init_context,
|
|
||||||
},
|
},
|
||||||
protocol::tests::file_to_json_object,
|
protocol::tests::file_to_json_object,
|
||||||
};
|
};
|
||||||
|
@ -234,7 +233,7 @@ pub(crate) mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
pub(crate) async fn test_parse_lemmy_comment() {
|
pub(crate) async fn test_parse_lemmy_comment() {
|
||||||
let context = init_context().await;
|
let context = LemmyContext::init_test_context().await;
|
||||||
let url = Url::parse("https://enterprise.lemmy.ml/comment/38741").unwrap();
|
let url = Url::parse("https://enterprise.lemmy.ml/comment/38741").unwrap();
|
||||||
let data = prepare_comment_test(&url, &context).await;
|
let data = prepare_comment_test(&url, &context).await;
|
||||||
|
|
||||||
|
@ -262,7 +261,7 @@ pub(crate) mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn test_parse_pleroma_comment() {
|
async fn test_parse_pleroma_comment() {
|
||||||
let context = init_context().await;
|
let context = LemmyContext::init_test_context().await;
|
||||||
let url = Url::parse("https://enterprise.lemmy.ml/comment/38741").unwrap();
|
let url = Url::parse("https://enterprise.lemmy.ml/comment/38741").unwrap();
|
||||||
let data = prepare_comment_test(&url, &context).await;
|
let data = prepare_comment_test(&url, &context).await;
|
||||||
|
|
||||||
|
|
|
@ -261,7 +261,7 @@ pub(crate) mod tests {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
objects::{instance::tests::parse_lemmy_instance, tests::init_context},
|
objects::instance::tests::parse_lemmy_instance,
|
||||||
protocol::tests::file_to_json_object,
|
protocol::tests::file_to_json_object,
|
||||||
};
|
};
|
||||||
use activitypub_federation::fetch::collection_id::CollectionId;
|
use activitypub_federation::fetch::collection_id::CollectionId;
|
||||||
|
@ -290,7 +290,7 @@ pub(crate) mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn test_parse_lemmy_community() {
|
async fn test_parse_lemmy_community() {
|
||||||
let context = init_context().await;
|
let context = LemmyContext::init_test_context().await;
|
||||||
let site = parse_lemmy_instance(&context).await;
|
let site = parse_lemmy_instance(&context).await;
|
||||||
let community = parse_lemmy_community(&context).await;
|
let community = parse_lemmy_community(&context).await;
|
||||||
|
|
||||||
|
|
|
@ -218,7 +218,7 @@ pub(crate) mod tests {
|
||||||
#![allow(clippy::indexing_slicing)]
|
#![allow(clippy::indexing_slicing)]
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{objects::tests::init_context, protocol::tests::file_to_json_object};
|
use crate::protocol::tests::file_to_json_object;
|
||||||
use lemmy_db_schema::traits::Crud;
|
use lemmy_db_schema::traits::Crud;
|
||||||
use serial_test::serial;
|
use serial_test::serial;
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ pub(crate) mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn test_parse_lemmy_instance() {
|
async fn test_parse_lemmy_instance() {
|
||||||
let context = init_context().await;
|
let context = LemmyContext::init_test_context().await;
|
||||||
let site = parse_lemmy_instance(&context).await;
|
let site = parse_lemmy_instance(&context).await;
|
||||||
|
|
||||||
assert_eq!(site.name, "Enterprise");
|
assert_eq!(site.name, "Enterprise");
|
||||||
|
|
|
@ -51,58 +51,3 @@ pub(crate) fn verify_is_remote_object(id: &Url, settings: &Settings) -> Result<(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
pub(crate) mod tests {
|
|
||||||
#![allow(clippy::unwrap_used)]
|
|
||||||
#![allow(clippy::indexing_slicing)]
|
|
||||||
|
|
||||||
use activitypub_federation::config::{Data, FederationConfig};
|
|
||||||
use anyhow::anyhow;
|
|
||||||
use lemmy_api_common::{context::LemmyContext, request::client_builder};
|
|
||||||
use lemmy_db_schema::{source::secret::Secret, utils::build_db_pool_for_tests};
|
|
||||||
use lemmy_utils::{rate_limit::RateLimitCell, settings::SETTINGS};
|
|
||||||
use reqwest::{Request, Response};
|
|
||||||
use reqwest_middleware::{ClientBuilder, Middleware, Next};
|
|
||||||
use task_local_extensions::Extensions;
|
|
||||||
|
|
||||||
struct BlockedMiddleware;
|
|
||||||
|
|
||||||
/// A reqwest middleware which blocks all requests
|
|
||||||
#[async_trait::async_trait]
|
|
||||||
impl Middleware for BlockedMiddleware {
|
|
||||||
async fn handle(
|
|
||||||
&self,
|
|
||||||
_req: Request,
|
|
||||||
_extensions: &mut Extensions,
|
|
||||||
_next: Next<'_>,
|
|
||||||
) -> reqwest_middleware::Result<Response> {
|
|
||||||
Err(anyhow!("Network requests not allowed").into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: would be nice if we didnt have to use a full context for tests.
|
|
||||||
pub(crate) async fn init_context() -> Data<LemmyContext> {
|
|
||||||
// call this to run migrations
|
|
||||||
let pool = build_db_pool_for_tests().await;
|
|
||||||
|
|
||||||
let client = client_builder(&SETTINGS).build().unwrap();
|
|
||||||
|
|
||||||
let client = ClientBuilder::new(client).with(BlockedMiddleware).build();
|
|
||||||
let secret = Secret {
|
|
||||||
id: 0,
|
|
||||||
jwt_secret: String::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let rate_limit_cell = RateLimitCell::with_test_config();
|
|
||||||
|
|
||||||
let context = LemmyContext::create(pool, client, secret, rate_limit_cell.clone());
|
|
||||||
let config = FederationConfig::builder()
|
|
||||||
.domain("example.com")
|
|
||||||
.app_data(context)
|
|
||||||
.build()
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
config.to_request_data()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -224,10 +224,7 @@ pub(crate) mod tests {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
objects::{
|
objects::instance::{tests::parse_lemmy_instance, ApubSite},
|
||||||
instance::{tests::parse_lemmy_instance, ApubSite},
|
|
||||||
tests::init_context,
|
|
||||||
},
|
|
||||||
protocol::{objects::instance::Instance, tests::file_to_json_object},
|
protocol::{objects::instance::Instance, tests::file_to_json_object},
|
||||||
};
|
};
|
||||||
use activitypub_federation::fetch::object_id::ObjectId;
|
use activitypub_federation::fetch::object_id::ObjectId;
|
||||||
|
@ -247,7 +244,7 @@ pub(crate) mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn test_parse_lemmy_person() {
|
async fn test_parse_lemmy_person() {
|
||||||
let context = init_context().await;
|
let context = LemmyContext::init_test_context().await;
|
||||||
let (person, site) = parse_lemmy_person(&context).await;
|
let (person, site) = parse_lemmy_person(&context).await;
|
||||||
|
|
||||||
assert_eq!(person.display_name, Some("Jean-Luc Picard".to_string()));
|
assert_eq!(person.display_name, Some("Jean-Luc Picard".to_string()));
|
||||||
|
@ -260,7 +257,7 @@ pub(crate) mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn test_parse_pleroma_person() {
|
async fn test_parse_pleroma_person() {
|
||||||
let context = init_context().await;
|
let context = LemmyContext::init_test_context().await;
|
||||||
|
|
||||||
// create and parse a fake pleroma instance actor, to avoid network request during test
|
// create and parse a fake pleroma instance actor, to avoid network request during test
|
||||||
let mut json: Instance = file_to_json_object("assets/lemmy/objects/instance.json").unwrap();
|
let mut json: Instance = file_to_json_object("assets/lemmy/objects/instance.json").unwrap();
|
||||||
|
|
|
@ -303,7 +303,6 @@ mod tests {
|
||||||
instance::ApubSite,
|
instance::ApubSite,
|
||||||
person::{tests::parse_lemmy_person, ApubPerson},
|
person::{tests::parse_lemmy_person, ApubPerson},
|
||||||
post::ApubPost,
|
post::ApubPost,
|
||||||
tests::init_context,
|
|
||||||
},
|
},
|
||||||
protocol::tests::file_to_json_object,
|
protocol::tests::file_to_json_object,
|
||||||
};
|
};
|
||||||
|
@ -313,7 +312,7 @@ mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn test_parse_lemmy_post() {
|
async fn test_parse_lemmy_post() {
|
||||||
let context = init_context().await;
|
let context = LemmyContext::init_test_context().await;
|
||||||
let (person, site) = parse_lemmy_person(&context).await;
|
let (person, site) = parse_lemmy_person(&context).await;
|
||||||
let community = parse_lemmy_community(&context).await;
|
let community = parse_lemmy_community(&context).await;
|
||||||
|
|
||||||
|
@ -336,7 +335,7 @@ mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn test_convert_mastodon_post_title() {
|
async fn test_convert_mastodon_post_title() {
|
||||||
let context = init_context().await;
|
let context = LemmyContext::init_test_context().await;
|
||||||
let (person, site) = parse_lemmy_person(&context).await;
|
let (person, site) = parse_lemmy_person(&context).await;
|
||||||
let community = parse_lemmy_community(&context).await;
|
let community = parse_lemmy_community(&context).await;
|
||||||
|
|
||||||
|
|
|
@ -156,7 +156,6 @@ mod tests {
|
||||||
objects::{
|
objects::{
|
||||||
instance::{tests::parse_lemmy_instance, ApubSite},
|
instance::{tests::parse_lemmy_instance, ApubSite},
|
||||||
person::ApubPerson,
|
person::ApubPerson,
|
||||||
tests::init_context,
|
|
||||||
},
|
},
|
||||||
protocol::tests::file_to_json_object,
|
protocol::tests::file_to_json_object,
|
||||||
};
|
};
|
||||||
|
@ -201,7 +200,7 @@ mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn test_parse_lemmy_pm() {
|
async fn test_parse_lemmy_pm() {
|
||||||
let context = init_context().await;
|
let context = LemmyContext::init_test_context().await;
|
||||||
let url = Url::parse("https://enterprise.lemmy.ml/private_message/1621").unwrap();
|
let url = Url::parse("https://enterprise.lemmy.ml/private_message/1621").unwrap();
|
||||||
let data = prepare_comment_test(&url, &context).await;
|
let data = prepare_comment_test(&url, &context).await;
|
||||||
let json: ChatMessage = file_to_json_object("assets/lemmy/objects/chat_message.json").unwrap();
|
let json: ChatMessage = file_to_json_object("assets/lemmy/objects/chat_message.json").unwrap();
|
||||||
|
@ -229,7 +228,7 @@ mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn test_parse_pleroma_pm() {
|
async fn test_parse_pleroma_pm() {
|
||||||
let context = init_context().await;
|
let context = LemmyContext::init_test_context().await;
|
||||||
let url = Url::parse("https://enterprise.lemmy.ml/private_message/1621").unwrap();
|
let url = Url::parse("https://enterprise.lemmy.ml/private_message/1621").unwrap();
|
||||||
let data = prepare_comment_test(&url, &context).await;
|
let data = prepare_comment_test(&url, &context).await;
|
||||||
let pleroma_url = Url::parse("https://queer.hacktivis.me/objects/2").unwrap();
|
let pleroma_url = Url::parse("https://queer.hacktivis.me/objects/2").unwrap();
|
||||||
|
|
|
@ -28,10 +28,7 @@ use diesel_async::{
|
||||||
};
|
};
|
||||||
use diesel_migrations::EmbeddedMigrations;
|
use diesel_migrations::EmbeddedMigrations;
|
||||||
use futures_util::{future::BoxFuture, Future, FutureExt};
|
use futures_util::{future::BoxFuture, Future, FutureExt};
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{error::LemmyError, settings::structs::Settings};
|
||||||
error::{LemmyError, LemmyErrorExt, LemmyErrorType},
|
|
||||||
settings::structs::Settings,
|
|
||||||
};
|
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use rustls::{
|
use rustls::{
|
||||||
|
@ -212,32 +209,6 @@ pub fn diesel_option_overwrite(opt: Option<String>) -> Option<Option<String>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn diesel_option_overwrite_to_url(
|
|
||||||
opt: &Option<String>,
|
|
||||||
) -> Result<Option<Option<DbUrl>>, LemmyError> {
|
|
||||||
match opt.as_ref().map(String::as_str) {
|
|
||||||
// An empty string is an erase
|
|
||||||
Some("") => Ok(Some(None)),
|
|
||||||
Some(str_url) => Url::parse(str_url)
|
|
||||||
.map(|u| Some(Some(u.into())))
|
|
||||||
.with_lemmy_type(LemmyErrorType::InvalidUrl),
|
|
||||||
None => Ok(None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn diesel_option_overwrite_to_url_create(
|
|
||||||
opt: &Option<String>,
|
|
||||||
) -> Result<Option<DbUrl>, LemmyError> {
|
|
||||||
match opt.as_ref().map(String::as_str) {
|
|
||||||
// An empty string is nothing
|
|
||||||
Some("") => Ok(None),
|
|
||||||
Some(str_url) => Url::parse(str_url)
|
|
||||||
.map(|u| Some(u.into()))
|
|
||||||
.with_lemmy_type(LemmyErrorType::InvalidUrl),
|
|
||||||
None => Ok(None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn build_db_pool_settings_opt(
|
async fn build_db_pool_settings_opt(
|
||||||
settings: Option<&Settings>,
|
settings: Option<&Settings>,
|
||||||
) -> Result<ActualDbPool, LemmyError> {
|
) -> Result<ActualDbPool, LemmyError> {
|
||||||
|
@ -516,19 +487,4 @@ mod tests {
|
||||||
Some(Some("test".to_string()))
|
Some(Some("test".to_string()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_diesel_option_overwrite_to_url() {
|
|
||||||
assert!(matches!(diesel_option_overwrite_to_url(&None), Ok(None)));
|
|
||||||
assert!(matches!(
|
|
||||||
diesel_option_overwrite_to_url(&Some(String::new())),
|
|
||||||
Ok(Some(None))
|
|
||||||
));
|
|
||||||
assert!(diesel_option_overwrite_to_url(&Some("invalid_url".to_string())).is_err());
|
|
||||||
let example_url = "https://example.com";
|
|
||||||
assert!(matches!(
|
|
||||||
diesel_option_overwrite_to_url(&Some(example_url.to_string())),
|
|
||||||
Ok(Some(Some(url))) if url == Url::parse(example_url).unwrap().into()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue