mirror of https://github.com/LemmyNet/lemmy.git
Adding tests.
parent
925a61ffed
commit
910fe9560a
|
@ -456,8 +456,6 @@ async fn update_banned_when_expired(pool: &mut DbPool<'_>) {
|
|||
/// https://github.com/jhass/nodeinfo/blob/main/PROTOCOL.md
|
||||
///
|
||||
/// TODO: if instance has been dead for a long time, it should be checked less frequently
|
||||
/// TODO This function is a bit of a nightmare with its embedded matches, but the only other way
|
||||
/// would be to extract the fetches into functions which return the default_form on errors.
|
||||
async fn update_instance_software(
|
||||
pool: &mut DbPool<'_>,
|
||||
client: &ClientWithMiddleware,
|
||||
|
@ -470,20 +468,43 @@ async fn update_instance_software(
|
|||
let instances = instance::table.get_results::<Instance>(&mut conn).await?;
|
||||
|
||||
for instance in instances {
|
||||
if let Some(form) = build_update_instance_form(&instance.domain, client).await {
|
||||
Instance::update(pool, instance.id, form).await?;
|
||||
}
|
||||
}
|
||||
info!("Finished updating instances software and versions...");
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to get connection from pool: {e}");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// This builds an instance update form, for a given domain.
|
||||
/// If the instance sends a response, but doesn't have a well-known or nodeinfo,
|
||||
/// Then return a default form with only the updated field.
|
||||
///
|
||||
/// TODO This function is a bit of a nightmare with its embedded matches, but the only other way
|
||||
/// would be to extract the fetches into functions which return the default_form on errors.
|
||||
async fn build_update_instance_form(
|
||||
domain: &str,
|
||||
client: &ClientWithMiddleware,
|
||||
) -> Option<InstanceForm> {
|
||||
// The `updated` column is used to check if instances are alive. If it is more than three
|
||||
// days in the past, no outgoing activities will be sent to that instance. However
|
||||
// not every Fediverse instance has a valid Nodeinfo endpoint (its not required for
|
||||
// Activitypub). That's why we always need to mark instances as updated if they are
|
||||
// alive.
|
||||
let mut instance_form = InstanceForm::builder()
|
||||
.domain(instance.domain.clone())
|
||||
.domain(domain.to_string())
|
||||
.updated(Some(naive_now()))
|
||||
.build();
|
||||
|
||||
// First, fetch their /.well-known/nodeinfo, then extract the correct nodeinfo link from it
|
||||
let well_known_url = format!("https://{}/.well-known/nodeinfo", instance.domain);
|
||||
let well_known_url = format!("https://{}/.well-known/nodeinfo", domain);
|
||||
|
||||
let form = match client.get(&well_known_url).send().await {
|
||||
match client.get(&well_known_url).send().await {
|
||||
Ok(res) if res.status().is_client_error() => {
|
||||
// Instance doesn't have well-known but sent a response, consider it alive
|
||||
Some(instance_form)
|
||||
|
@ -530,42 +551,44 @@ async fn update_instance_software(
|
|||
// dead instance, do nothing
|
||||
None
|
||||
}
|
||||
};
|
||||
if let Some(form) = form {
|
||||
Instance::update(pool, instance.id, form).await?;
|
||||
}
|
||||
}
|
||||
info!("Finished updating instances software and versions...");
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to get connection from pool: {e}");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(clippy::unwrap_used)]
|
||||
#[allow(clippy::indexing_slicing)]
|
||||
mod tests {
|
||||
|
||||
use lemmy_routes::nodeinfo::NodeInfo;
|
||||
use crate::scheduled_tasks::build_update_instance_form;
|
||||
use lemmy_api_common::request::client_builder;
|
||||
use lemmy_utils::{error::LemmyResult, settings::structs::Settings, LemmyErrorType};
|
||||
use pretty_assertions::assert_eq;
|
||||
use reqwest::Client;
|
||||
use reqwest_middleware::ClientBuilder;
|
||||
use serial_test::serial;
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore]
|
||||
async fn test_nodeinfo() {
|
||||
let client = Client::builder().build().unwrap();
|
||||
let lemmy_ml_nodeinfo = client
|
||||
.get("https://lemmy.ml/nodeinfo/2.0.json")
|
||||
.send()
|
||||
#[serial]
|
||||
async fn test_nodeinfo_voyager_lemmy_ml() -> LemmyResult<()> {
|
||||
let client = ClientBuilder::new(client_builder(&Settings::default()).build()?).build();
|
||||
let form = build_update_instance_form("voyager.lemmy.ml", &client)
|
||||
.await
|
||||
.unwrap()
|
||||
.json::<NodeInfo>()
|
||||
.await
|
||||
.unwrap();
|
||||
.ok_or(LemmyErrorType::CouldntFindObject)?;
|
||||
assert_eq!(
|
||||
form.software.ok_or(LemmyErrorType::CouldntFindObject)?,
|
||||
"lemmy"
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
assert_eq!(lemmy_ml_nodeinfo.software.unwrap().name.unwrap(), "lemmy");
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn test_nodeinfo_mastodon_social() -> LemmyResult<()> {
|
||||
let client = ClientBuilder::new(client_builder(&Settings::default()).build()?).build();
|
||||
let form = build_update_instance_form("mastodon.social", &client)
|
||||
.await
|
||||
.ok_or(LemmyErrorType::CouldntFindObject)?;
|
||||
assert_eq!(
|
||||
form.software.ok_or(LemmyErrorType::CouldntFindObject)?,
|
||||
"mastodon"
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue