From 762b85b27e812856f65933a182188e7102617aae Mon Sep 17 00:00:00 2001 From: Nutomic Date: Thu, 17 Feb 2022 22:04:01 +0000 Subject: [PATCH] Reorganize federation tests (#2092) * Reorganize apub protocol tests * Reorder apub protocol struct members to clarify mandatory/optional fields --- .../apub/assets/lemmy/objects/instance.json | 19 ----- crates/apub/assets/lemmy/objects/person.json | 2 +- .../mastodon/activities/create_note.json | 7 ++ .../assets/mastodon/activities/follow.json | 7 ++ .../mastodon/activities/undo_follow.json | 13 ++++ .../apub/assets/smithereen/objects/note.json | 8 +- .../src/collections/community_moderators.rs | 11 ++- crates/apub/src/objects/comment.rs | 16 ++-- crates/apub/src/objects/community.rs | 7 +- crates/apub/src/objects/instance.rs | 5 +- crates/apub/src/objects/mod.rs | 9 +-- crates/apub/src/objects/person.rs | 5 +- crates/apub/src/objects/post.rs | 14 ++-- crates/apub/src/objects/private_message.rs | 7 +- .../protocol/activities/block/block_user.rs | 5 +- .../apub/src/protocol/activities/block/mod.rs | 4 +- .../activities/block/undo_block_user.rs | 1 + .../protocol/activities/community/add_mod.rs | 1 + .../protocol/activities/community/announce.rs | 1 + .../src/protocol/activities/community/mod.rs | 4 +- .../activities/community/remove_mod.rs | 1 + .../protocol/activities/community/report.rs | 1 + .../protocol/activities/community/update.rs | 1 + .../activities/create_or_update/comment.rs | 1 + .../activities/create_or_update/mod.rs | 38 ++------- .../activities/create_or_update/post.rs | 1 + .../create_or_update/private_message.rs | 1 + .../protocol/activities/deletion/delete.rs | 7 +- .../src/protocol/activities/deletion/mod.rs | 17 ++-- .../activities/deletion/undo_delete.rs | 7 +- .../protocol/activities/following/accept.rs | 1 + .../protocol/activities/following/follow.rs | 1 + .../src/protocol/activities/following/mod.rs | 23 ++---- .../activities/following/undo_follow.rs | 1 + crates/apub/src/protocol/activities/mod.rs | 43 +++++++++++ .../src/protocol/activities/voting/mod.rs | 4 +- .../protocol/activities/voting/undo_vote.rs | 1 + .../src/protocol/activities/voting/vote.rs | 1 + crates/apub/src/protocol/collections/mod.rs | 4 +- crates/apub/src/protocol/mod.rs | 14 +++- .../apub/src/protocol/objects/chat_message.rs | 5 +- crates/apub/src/protocol/objects/group.rs | 15 ++-- crates/apub/src/protocol/objects/instance.rs | 13 ++-- crates/apub/src/protocol/objects/mod.rs | 77 +++++++++---------- crates/apub/src/protocol/objects/note.rs | 7 +- crates/apub/src/protocol/objects/page.rs | 7 +- crates/apub/src/protocol/objects/person.rs | 17 ++-- 47 files changed, 244 insertions(+), 211 deletions(-) create mode 100644 crates/apub/assets/mastodon/activities/follow.json create mode 100644 crates/apub/assets/mastodon/activities/undo_follow.json diff --git a/crates/apub/assets/lemmy/objects/instance.json b/crates/apub/assets/lemmy/objects/instance.json index 73df87759..524055f33 100644 --- a/crates/apub/assets/lemmy/objects/instance.json +++ b/crates/apub/assets/lemmy/objects/instance.json @@ -1,23 +1,4 @@ { - "@context": [ - "https://www.w3.org/ns/activitystreams", - { - "stickied": "as:stickied", - "pt": "https://join-lemmy.org#", - "sc": "http://schema.org#", - "matrixUserId": { - "type": "sc:Text", - "id": "as:alsoKnownAs" - }, - "sensitive": "as:sensitive", - "comments_enabled": { - "type": "sc:Boolean", - "id": "pt:commentsEnabled" - }, - "moderators": "as:moderators" - }, - "https://w3id.org/security/v1" - ], "type": "Service", "id": "https://enterprise.lemmy.ml/", "name": "Enterprise", diff --git a/crates/apub/assets/lemmy/objects/person.json b/crates/apub/assets/lemmy/objects/person.json index e21fa4d22..4f708656c 100644 --- a/crates/apub/assets/lemmy/objects/person.json +++ b/crates/apub/assets/lemmy/objects/person.json @@ -16,7 +16,7 @@ "type": "Image", "url": "https://enterprise.lemmy.ml/pictrs/image/XenaYI5hTn.png" }, - "matrix_user_id": "@picard:matrix.org", + "matrixUserId": "@picard:matrix.org", "inbox": "https://enterprise.lemmy.ml/u/picard/inbox", "outbox": "https://enterprise.lemmy.ml/u/picard/outbox", "endpoints": { diff --git a/crates/apub/assets/mastodon/activities/create_note.json b/crates/apub/assets/mastodon/activities/create_note.json index 8b836fb24..d796a043e 100644 --- a/crates/apub/assets/mastodon/activities/create_note.json +++ b/crates/apub/assets/mastodon/activities/create_note.json @@ -1,4 +1,11 @@ { + "@context": [ + "https://www.w3.org/ns/activitystreams", + { + "ostatus": "http://ostatus.org#", + "atomUri": "ostatus:atomUri" + } + ], "id": "https://mastodon.madrid/users/felix/statuses/107224289116410645/activity", "type": "Create", "actor": "https://mastodon.madrid/users/felix", diff --git a/crates/apub/assets/mastodon/activities/follow.json b/crates/apub/assets/mastodon/activities/follow.json new file mode 100644 index 000000000..2381ed521 --- /dev/null +++ b/crates/apub/assets/mastodon/activities/follow.json @@ -0,0 +1,7 @@ +{ + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://masto.asonix.dog/1ea87517-63c5-4118-8831-460ee641b2cf", + "type": "Follow", + "actor": "https://masto.asonix.dog/users/asonix", + "object": "https://ds9.lemmy.ml/c/testcom" +} diff --git a/crates/apub/assets/mastodon/activities/undo_follow.json b/crates/apub/assets/mastodon/activities/undo_follow.json new file mode 100644 index 000000000..d47ecd886 --- /dev/null +++ b/crates/apub/assets/mastodon/activities/undo_follow.json @@ -0,0 +1,13 @@ +{ + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://masto.asonix.dog/users/asonix#follows/449/undo", + "type": "Undo", + "actor": "https://masto.asonix.dog/users/asonix", + "object": { + "id": "https://masto.asonix.dog/1ea87517-63c5-4118-8831-460ee641b2cf", + "type": "Follow", + "actor": "https://masto.asonix.dog/users/asonix", + "object": "https://ds9.lemmy.ml/c/testcom" + } +} + diff --git a/crates/apub/assets/smithereen/objects/note.json b/crates/apub/assets/smithereen/objects/note.json index 0a948ee3d..a8080cae1 100644 --- a/crates/apub/assets/smithereen/objects/note.json +++ b/crates/apub/assets/smithereen/objects/note.json @@ -28,5 +28,11 @@ } }, "sensitive": false, - "likes": "https://friends.grishka.me/posts/66561/likes" + "likes": "https://friends.grishka.me/posts/66561/likes", + "@context": [ + "https://www.w3.org/ns/activitystreams", + { + "sensitive": "as:sensitive" + } + ] } \ No newline at end of file diff --git a/crates/apub/src/collections/community_moderators.rs b/crates/apub/src/collections/community_moderators.rs index 72d23d4ac..d24f06a13 100644 --- a/crates/apub/src/collections/community_moderators.rs +++ b/crates/apub/src/collections/community_moderators.rs @@ -138,10 +138,13 @@ impl ApubObject for ApubCommunityModerators { #[cfg(test)] mod tests { use super::*; - use crate::objects::{ - community::tests::parse_lemmy_community, - person::tests::parse_lemmy_person, - tests::{file_to_json_object, init_context}, + use crate::{ + objects::{ + community::tests::parse_lemmy_community, + person::tests::parse_lemmy_person, + tests::init_context, + }, + protocol::tests::file_to_json_object, }; use lemmy_apub_lib::activity_queue::create_activity_queue; use lemmy_db_schema::{ diff --git a/crates/apub/src/objects/comment.rs b/crates/apub/src/objects/comment.rs index 82d9e4e44..e61cb8699 100644 --- a/crates/apub/src/objects/comment.rs +++ b/crates/apub/src/objects/comment.rs @@ -125,7 +125,6 @@ impl ApubObject for ApubComment { published: Some(convert_datetime(self.published)), updated: self.updated.map(convert_datetime), tag: maa.tags, - unparsed: Default::default(), }; Ok(note) @@ -208,12 +207,15 @@ impl ApubObject for ApubComment { #[cfg(test)] pub(crate) mod tests { use super::*; - use crate::objects::{ - community::{tests::parse_lemmy_community, ApubCommunity}, - instance::ApubSite, - person::{tests::parse_lemmy_person, ApubPerson}, - post::ApubPost, - tests::{file_to_json_object, init_context}, + use crate::{ + objects::{ + community::{tests::parse_lemmy_community, ApubCommunity}, + instance::ApubSite, + person::{tests::parse_lemmy_person, ApubPerson}, + post::ApubPost, + tests::init_context, + }, + protocol::tests::file_to_json_object, }; use assert_json_diff::assert_json_include; use lemmy_apub_lib::activity_queue::create_activity_queue; diff --git a/crates/apub/src/objects/community.rs b/crates/apub/src/objects/community.rs index 4a618bf88..612616cf9 100644 --- a/crates/apub/src/objects/community.rs +++ b/crates/apub/src/objects/community.rs @@ -102,7 +102,6 @@ impl ApubObject for ApubCommunity { public_key: self.get_public_key()?, published: Some(convert_datetime(self.published)), updated: self.updated.map(convert_datetime), - unparsed: Default::default(), }; Ok(group) } @@ -214,9 +213,9 @@ impl ApubCommunity { #[cfg(test)] pub(crate) mod tests { use super::*; - use crate::objects::{ - instance::tests::parse_lemmy_instance, - tests::{file_to_json_object, init_context}, + use crate::{ + objects::{instance::tests::parse_lemmy_instance, tests::init_context}, + protocol::tests::file_to_json_object, }; use lemmy_apub_lib::activity_queue::create_activity_queue; use lemmy_db_schema::{source::site::Site, traits::Crud}; diff --git a/crates/apub/src/objects/instance.rs b/crates/apub/src/objects/instance.rs index cdd76c5a9..40b585b5a 100644 --- a/crates/apub/src/objects/instance.rs +++ b/crates/apub/src/objects/instance.rs @@ -1,7 +1,7 @@ use crate::{ check_is_apub_id_valid, objects::get_summary_from_string_or_source, - protocol::{objects::instance::Instance, ImageObject, Source, Unparsed}, + protocol::{objects::instance::Instance, ImageObject, Source}, }; use activitystreams_kinds::actor::ServiceType; use chrono::NaiveDateTime; @@ -86,7 +86,6 @@ impl ApubObject for ApubSite { public_key: self.get_public_key()?, published: convert_datetime(self.published), updated: self.updated.map(convert_datetime), - unparsed: Unparsed::default(), }; Ok(instance) } @@ -186,7 +185,7 @@ pub(in crate::objects) async fn fetch_instance_actor_for_object( #[cfg(test)] pub(crate) mod tests { use super::*; - use crate::objects::tests::{file_to_json_object, init_context}; + use crate::{objects::tests::init_context, protocol::tests::file_to_json_object}; use lemmy_apub_lib::activity_queue::create_activity_queue; use lemmy_db_schema::traits::Crud; use serial_test::serial; diff --git a/crates/apub/src/objects/mod.rs b/crates/apub/src/objects/mod.rs index d7e386b10..cfe1ecd36 100644 --- a/crates/apub/src/objects/mod.rs +++ b/crates/apub/src/objects/mod.rs @@ -41,8 +41,7 @@ pub(crate) mod tests { use lemmy_websocket::{chat_server::ChatServer, LemmyContext}; use reqwest::Client; use reqwest_middleware::ClientBuilder; - use serde::de::DeserializeOwned; - use std::{fs::File, io::BufReader, sync::Arc}; + use std::sync::Arc; use tokio::sync::Mutex; // TODO: would be nice if we didnt have to use a full context for tests. @@ -90,10 +89,4 @@ pub(crate) mod tests { .start(); LemmyContext::create(pool, chat_server, client, activity_queue, settings, secret) } - - pub(crate) fn file_to_json_object(path: &str) -> Result { - let file = File::open(path)?; - let reader = BufReader::new(file); - Ok(serde_json::from_reader(reader)?) - } } diff --git a/crates/apub/src/objects/person.rs b/crates/apub/src/objects/person.rs index 80dd8bfd1..b75b107a1 100644 --- a/crates/apub/src/objects/person.rs +++ b/crates/apub/src/objects/person.rs @@ -105,7 +105,6 @@ impl ApubObject for ApubPerson { }), public_key: self.get_public_key()?, updated: self.updated.map(convert_datetime), - unparsed: Default::default(), inbox: self.inbox_url.clone().into(), }; Ok(person) @@ -204,9 +203,9 @@ pub(crate) mod tests { use crate::{ objects::{ instance::{tests::parse_lemmy_instance, ApubSite}, - tests::{file_to_json_object, init_context}, + tests::init_context, }, - protocol::objects::instance::Instance, + protocol::{objects::instance::Instance, tests::file_to_json_object}, }; use lemmy_apub_lib::activity_queue::create_activity_queue; use lemmy_db_schema::{source::site::Site, traits::Crud}; diff --git a/crates/apub/src/objects/post.rs b/crates/apub/src/objects/post.rs index b15c9374b..3fb4b9cfd 100644 --- a/crates/apub/src/objects/post.rs +++ b/crates/apub/src/objects/post.rs @@ -122,7 +122,6 @@ impl ApubObject for ApubPost { stickied: Some(self.stickied), published: Some(convert_datetime(self.published)), updated: self.updated.map(convert_datetime), - unparsed: Default::default(), }; Ok(page) } @@ -207,11 +206,14 @@ impl ApubObject for ApubPost { #[cfg(test)] mod tests { use super::*; - use crate::objects::{ - community::tests::parse_lemmy_community, - person::tests::parse_lemmy_person, - post::ApubPost, - tests::{file_to_json_object, init_context}, + use crate::{ + objects::{ + community::tests::parse_lemmy_community, + person::tests::parse_lemmy_person, + post::ApubPost, + tests::init_context, + }, + protocol::tests::file_to_json_object, }; use lemmy_apub_lib::activity_queue::create_activity_queue; use lemmy_db_schema::source::site::Site; diff --git a/crates/apub/src/objects/private_message.rs b/crates/apub/src/objects/private_message.rs index 62af38553..329767fdd 100644 --- a/crates/apub/src/objects/private_message.rs +++ b/crates/apub/src/objects/private_message.rs @@ -90,7 +90,6 @@ impl ApubObject for ApubPrivateMessage { source: Some(Source::new(self.content.clone())), published: Some(convert_datetime(self.published)), updated: self.updated.map(convert_datetime), - unparsed: Default::default(), }; Ok(note) } @@ -159,9 +158,9 @@ impl ApubObject for ApubPrivateMessage { #[cfg(test)] mod tests { use super::*; - use crate::objects::{ - person::ApubPerson, - tests::{file_to_json_object, init_context}, + use crate::{ + objects::{person::ApubPerson, tests::init_context}, + protocol::tests::file_to_json_object, }; use assert_json_diff::assert_json_include; use lemmy_apub_lib::activity_queue::create_activity_queue; diff --git a/crates/apub/src/protocol/activities/block/block_user.rs b/crates/apub/src/protocol/activities/block/block_user.rs index 5d49fc602..ab4e3eca9 100644 --- a/crates/apub/src/protocol/activities/block/block_user.rs +++ b/crates/apub/src/protocol/activities/block/block_user.rs @@ -17,13 +17,14 @@ pub struct BlockUser { pub(crate) target: ObjectId, #[serde(rename = "type")] pub(crate) kind: BlockType, + pub(crate) id: Url, + /// Quick and dirty solution. /// TODO: send a separate Delete activity instead pub(crate) remove_data: Option, /// block reason, written to mod log pub(crate) summary: Option, - pub(crate) id: Url, + pub(crate) expires: Option>, #[serde(flatten)] pub(crate) unparsed: Unparsed, - pub(crate) expires: Option>, } diff --git a/crates/apub/src/protocol/activities/block/mod.rs b/crates/apub/src/protocol/activities/block/mod.rs index eb3736f76..eaf05b9ac 100644 --- a/crates/apub/src/protocol/activities/block/mod.rs +++ b/crates/apub/src/protocol/activities/block/mod.rs @@ -8,8 +8,8 @@ mod tests { tests::test_parse_lemmy_item, }; - #[actix_rt::test] - async fn test_parse_lemmy_block() { + #[test] + fn test_parse_lemmy_block() { test_parse_lemmy_item::("assets/lemmy/activities/block/block_user.json").unwrap(); test_parse_lemmy_item::("assets/lemmy/activities/block/undo_block_user.json") .unwrap(); diff --git a/crates/apub/src/protocol/activities/block/undo_block_user.rs b/crates/apub/src/protocol/activities/block/undo_block_user.rs index d3db580e4..8e756be55 100644 --- a/crates/apub/src/protocol/activities/block/undo_block_user.rs +++ b/crates/apub/src/protocol/activities/block/undo_block_user.rs @@ -19,6 +19,7 @@ pub struct UndoBlockUser { #[serde(rename = "type")] pub(crate) kind: UndoType, pub(crate) id: Url, + #[serde(flatten)] pub(crate) unparsed: Unparsed, } diff --git a/crates/apub/src/protocol/activities/community/add_mod.rs b/crates/apub/src/protocol/activities/community/add_mod.rs index 915c24668..5697c19f4 100644 --- a/crates/apub/src/protocol/activities/community/add_mod.rs +++ b/crates/apub/src/protocol/activities/community/add_mod.rs @@ -17,6 +17,7 @@ pub struct AddMod { #[serde(rename = "type")] pub(crate) kind: AddType, pub(crate) id: Url, + #[serde(flatten)] pub(crate) unparsed: Unparsed, } diff --git a/crates/apub/src/protocol/activities/community/announce.rs b/crates/apub/src/protocol/activities/community/announce.rs index 0bda9ebc5..d693ed6f7 100644 --- a/crates/apub/src/protocol/activities/community/announce.rs +++ b/crates/apub/src/protocol/activities/community/announce.rs @@ -20,6 +20,7 @@ pub struct AnnounceActivity { #[serde(rename = "type")] pub(crate) kind: AnnounceType, pub(crate) id: Url, + #[serde(flatten)] pub(crate) unparsed: Unparsed, } diff --git a/crates/apub/src/protocol/activities/community/mod.rs b/crates/apub/src/protocol/activities/community/mod.rs index a25d5ca2d..47771891f 100644 --- a/crates/apub/src/protocol/activities/community/mod.rs +++ b/crates/apub/src/protocol/activities/community/mod.rs @@ -17,8 +17,8 @@ mod tests { tests::test_parse_lemmy_item, }; - #[actix_rt::test] - async fn test_parse_lemmy_community() { + #[test] + fn test_parse_lemmy_community_activities() { test_parse_lemmy_item::( "assets/lemmy/activities/community/announce_create_page.json", ) diff --git a/crates/apub/src/protocol/activities/community/remove_mod.rs b/crates/apub/src/protocol/activities/community/remove_mod.rs index 74619c81d..304772bb2 100644 --- a/crates/apub/src/protocol/activities/community/remove_mod.rs +++ b/crates/apub/src/protocol/activities/community/remove_mod.rs @@ -17,6 +17,7 @@ pub struct RemoveMod { pub(crate) kind: RemoveType, pub(crate) target: Url, pub(crate) id: Url, + #[serde(flatten)] pub(crate) unparsed: Unparsed, } diff --git a/crates/apub/src/protocol/activities/community/report.rs b/crates/apub/src/protocol/activities/community/report.rs index 18b74c238..40bbe83bd 100644 --- a/crates/apub/src/protocol/activities/community/report.rs +++ b/crates/apub/src/protocol/activities/community/report.rs @@ -19,6 +19,7 @@ pub struct Report { #[serde(rename = "type")] pub(crate) kind: FlagType, pub(crate) id: Url, + #[serde(flatten)] pub(crate) unparsed: Unparsed, } diff --git a/crates/apub/src/protocol/activities/community/update.rs b/crates/apub/src/protocol/activities/community/update.rs index bb9b56114..4c4ef2f03 100644 --- a/crates/apub/src/protocol/activities/community/update.rs +++ b/crates/apub/src/protocol/activities/community/update.rs @@ -22,6 +22,7 @@ pub struct UpdateCommunity { #[serde(rename = "type")] pub(crate) kind: UpdateType, pub(crate) id: Url, + #[serde(flatten)] pub(crate) unparsed: Unparsed, } diff --git a/crates/apub/src/protocol/activities/create_or_update/comment.rs b/crates/apub/src/protocol/activities/create_or_update/comment.rs index 091c0f97c..d63aabf84 100644 --- a/crates/apub/src/protocol/activities/create_or_update/comment.rs +++ b/crates/apub/src/protocol/activities/create_or_update/comment.rs @@ -21,6 +21,7 @@ pub struct CreateOrUpdateComment { #[serde(rename = "type")] pub(crate) kind: CreateOrUpdateType, pub(crate) id: Url, + #[serde(flatten)] pub(crate) unparsed: Unparsed, } diff --git a/crates/apub/src/protocol/activities/create_or_update/mod.rs b/crates/apub/src/protocol/activities/create_or_update/mod.rs index ff03c5a09..0d233ccfc 100644 --- a/crates/apub/src/protocol/activities/create_or_update/mod.rs +++ b/crates/apub/src/protocol/activities/create_or_update/mod.rs @@ -4,21 +4,17 @@ pub mod private_message; #[cfg(test)] mod tests { - use crate::{ - context::WithContext, - objects::tests::file_to_json_object, - protocol::{ - activities::create_or_update::{ - comment::CreateOrUpdateComment, - post::CreateOrUpdatePost, - private_message::CreateOrUpdatePrivateMessage, - }, - tests::test_parse_lemmy_item, + use crate::protocol::{ + activities::create_or_update::{ + comment::CreateOrUpdateComment, + post::CreateOrUpdatePost, + private_message::CreateOrUpdatePrivateMessage, }, + tests::test_parse_lemmy_item, }; - #[actix_rt::test] - async fn test_parse_create_or_update() { + #[test] + fn test_parse_lemmy_create_or_update() { test_parse_lemmy_item::( "assets/lemmy/activities/create_or_update/create_page.json", ) @@ -35,23 +31,5 @@ mod tests { "assets/lemmy/activities/create_or_update/create_private_message.json", ) .unwrap(); - - file_to_json_object::>( - "assets/pleroma/activities/create_note.json", - ) - .unwrap(); - file_to_json_object::>( - "assets/smithereen/activities/create_note.json", - ) - .unwrap(); - file_to_json_object::("assets/mastodon/activities/create_note.json") - .unwrap(); - - file_to_json_object::("assets/lotide/activities/create_page.json").unwrap(); - file_to_json_object::("assets/lotide/activities/create_note_reply.json") - .unwrap(); - - file_to_json_object::("assets/friendica/activities/create_note.json") - .unwrap(); } } diff --git a/crates/apub/src/protocol/activities/create_or_update/post.rs b/crates/apub/src/protocol/activities/create_or_update/post.rs index 2061c8815..eb96572f1 100644 --- a/crates/apub/src/protocol/activities/create_or_update/post.rs +++ b/crates/apub/src/protocol/activities/create_or_update/post.rs @@ -18,6 +18,7 @@ pub struct CreateOrUpdatePost { #[serde(rename = "type")] pub(crate) kind: CreateOrUpdateType, pub(crate) id: Url, + #[serde(flatten)] pub(crate) unparsed: Unparsed, } diff --git a/crates/apub/src/protocol/activities/create_or_update/private_message.rs b/crates/apub/src/protocol/activities/create_or_update/private_message.rs index 9558d074a..a4e62b656 100644 --- a/crates/apub/src/protocol/activities/create_or_update/private_message.rs +++ b/crates/apub/src/protocol/activities/create_or_update/private_message.rs @@ -16,6 +16,7 @@ pub struct CreateOrUpdatePrivateMessage { pub(crate) object: ChatMessage, #[serde(rename = "type")] pub(crate) kind: CreateOrUpdateType, + #[serde(flatten)] pub(crate) unparsed: Unparsed, } diff --git a/crates/apub/src/protocol/activities/deletion/delete.rs b/crates/apub/src/protocol/activities/deletion/delete.rs index 70b38af6c..6913652fa 100644 --- a/crates/apub/src/protocol/activities/deletion/delete.rs +++ b/crates/apub/src/protocol/activities/deletion/delete.rs @@ -13,16 +13,17 @@ pub struct Delete { #[serde(deserialize_with = "crate::deserialize_one_or_many")] pub(crate) to: Vec, pub(crate) object: IdOrNestedObject, + #[serde(rename = "type")] + pub(crate) kind: DeleteType, + pub(crate) id: Url, + #[serde(deserialize_with = "crate::deserialize_one_or_many")] #[serde(default)] #[serde(skip_serializing_if = "Vec::is_empty")] pub(crate) cc: Vec, - #[serde(rename = "type")] - pub(crate) kind: DeleteType, /// If summary is present, this is a mod action (Remove in Lemmy terms). Otherwise, its a user /// deleting their own content. pub(crate) summary: Option, - pub(crate) id: Url, #[serde(flatten)] pub(crate) unparsed: Unparsed, } diff --git a/crates/apub/src/protocol/activities/deletion/mod.rs b/crates/apub/src/protocol/activities/deletion/mod.rs index 9ecb65c4c..24f7ab16e 100644 --- a/crates/apub/src/protocol/activities/deletion/mod.rs +++ b/crates/apub/src/protocol/activities/deletion/mod.rs @@ -3,17 +3,13 @@ pub mod undo_delete; #[cfg(test)] mod tests { - use crate::{ - context::WithContext, - objects::tests::file_to_json_object, - protocol::{ - activities::deletion::{delete::Delete, undo_delete::UndoDelete}, - tests::test_parse_lemmy_item, - }, + use crate::protocol::{ + activities::deletion::{delete::Delete, undo_delete::UndoDelete}, + tests::test_parse_lemmy_item, }; - #[actix_rt::test] - async fn test_parse_deletion() { + #[test] + fn test_parse_lemmy_deletion() { test_parse_lemmy_item::("assets/lemmy/activities/deletion/remove_note.json").unwrap(); test_parse_lemmy_item::("assets/lemmy/activities/deletion/delete_page.json").unwrap(); @@ -27,8 +23,5 @@ mod tests { "assets/lemmy/activities/deletion/undo_delete_private_message.json", ) .unwrap(); - - file_to_json_object::>("assets/pleroma/activities/delete.json").unwrap(); - file_to_json_object::>("assets/mastodon/activities/delete.json").unwrap(); } } diff --git a/crates/apub/src/protocol/activities/deletion/undo_delete.rs b/crates/apub/src/protocol/activities/deletion/undo_delete.rs index f2f2d7644..bc5b942ff 100644 --- a/crates/apub/src/protocol/activities/deletion/undo_delete.rs +++ b/crates/apub/src/protocol/activities/deletion/undo_delete.rs @@ -14,13 +14,14 @@ pub struct UndoDelete { #[serde(deserialize_with = "crate::deserialize_one_or_many")] pub(crate) to: Vec, pub(crate) object: Delete, + #[serde(rename = "type")] + pub(crate) kind: UndoType, + pub(crate) id: Url, + #[serde(deserialize_with = "crate::deserialize_one_or_many")] #[serde(default)] #[serde(skip_serializing_if = "Vec::is_empty")] pub(crate) cc: Vec, - #[serde(rename = "type")] - pub(crate) kind: UndoType, - pub(crate) id: Url, #[serde(flatten)] pub(crate) unparsed: Unparsed, } diff --git a/crates/apub/src/protocol/activities/following/accept.rs b/crates/apub/src/protocol/activities/following/accept.rs index 09d3419a1..dcb0b181a 100644 --- a/crates/apub/src/protocol/activities/following/accept.rs +++ b/crates/apub/src/protocol/activities/following/accept.rs @@ -15,6 +15,7 @@ pub struct AcceptFollowCommunity { #[serde(rename = "type")] pub(crate) kind: AcceptType, pub(crate) id: Url, + #[serde(flatten)] pub(crate) unparsed: Unparsed, } diff --git a/crates/apub/src/protocol/activities/following/follow.rs b/crates/apub/src/protocol/activities/following/follow.rs index cc2cc8e0a..2072af486 100644 --- a/crates/apub/src/protocol/activities/following/follow.rs +++ b/crates/apub/src/protocol/activities/following/follow.rs @@ -15,6 +15,7 @@ pub struct FollowCommunity { #[serde(rename = "type")] pub(crate) kind: FollowType, pub(crate) id: Url, + #[serde(flatten)] pub(crate) unparsed: Unparsed, } diff --git a/crates/apub/src/protocol/activities/following/mod.rs b/crates/apub/src/protocol/activities/following/mod.rs index 2b21b4834..1265512f9 100644 --- a/crates/apub/src/protocol/activities/following/mod.rs +++ b/crates/apub/src/protocol/activities/following/mod.rs @@ -4,21 +4,17 @@ pub mod undo_follow; #[cfg(test)] mod tests { - use crate::{ - context::WithContext, - objects::tests::file_to_json_object, - protocol::{ - activities::following::{ - accept::AcceptFollowCommunity, - follow::FollowCommunity, - undo_follow::UndoFollowCommunity, - }, - tests::test_parse_lemmy_item, + use crate::protocol::{ + activities::following::{ + accept::AcceptFollowCommunity, + follow::FollowCommunity, + undo_follow::UndoFollowCommunity, }, + tests::test_parse_lemmy_item, }; - #[actix_rt::test] - async fn test_parse_lemmy_accept_follow() { + #[test] + fn test_parse_lemmy_accept_follow() { test_parse_lemmy_item::("assets/lemmy/activities/following/follow.json") .unwrap(); test_parse_lemmy_item::("assets/lemmy/activities/following/accept.json") @@ -27,8 +23,5 @@ mod tests { "assets/lemmy/activities/following/undo_follow.json", ) .unwrap(); - - file_to_json_object::>("assets/pleroma/activities/follow.json") - .unwrap(); } } diff --git a/crates/apub/src/protocol/activities/following/undo_follow.rs b/crates/apub/src/protocol/activities/following/undo_follow.rs index f14e3a48d..193614690 100644 --- a/crates/apub/src/protocol/activities/following/undo_follow.rs +++ b/crates/apub/src/protocol/activities/following/undo_follow.rs @@ -15,6 +15,7 @@ pub struct UndoFollowCommunity { #[serde(rename = "type")] pub(crate) kind: UndoType, pub(crate) id: Url, + #[serde(flatten)] pub(crate) unparsed: Unparsed, } diff --git a/crates/apub/src/protocol/activities/mod.rs b/crates/apub/src/protocol/activities/mod.rs index 9279cab12..0f9509319 100644 --- a/crates/apub/src/protocol/activities/mod.rs +++ b/crates/apub/src/protocol/activities/mod.rs @@ -13,3 +13,46 @@ pub enum CreateOrUpdateType { Create, Update, } + +#[cfg(test)] +mod tests { + use crate::protocol::{ + activities::{ + create_or_update::{comment::CreateOrUpdateComment, post::CreateOrUpdatePost}, + deletion::delete::Delete, + following::{follow::FollowCommunity, undo_follow::UndoFollowCommunity}, + }, + tests::test_json, + }; + + #[test] + fn test_parse_smithereen_activities() { + test_json::("assets/smithereen/activities/create_note.json").unwrap(); + } + + #[test] + fn test_parse_pleroma_activities() { + test_json::("assets/pleroma/activities/create_note.json").unwrap(); + test_json::("assets/pleroma/activities/delete.json").unwrap(); + test_json::("assets/pleroma/activities/follow.json").unwrap(); + } + + #[test] + fn test_parse_mastodon_activities() { + test_json::("assets/mastodon/activities/create_note.json").unwrap(); + test_json::("assets/mastodon/activities/delete.json").unwrap(); + test_json::("assets/mastodon/activities/follow.json").unwrap(); + test_json::("assets/mastodon/activities/undo_follow.json").unwrap(); + } + + #[test] + fn test_parse_lotide_activities() { + test_json::("assets/lotide/activities/create_page.json").unwrap(); + test_json::("assets/lotide/activities/create_note_reply.json").unwrap(); + } + + #[test] + fn test_parse_friendica_activities() { + test_json::("assets/friendica/activities/create_note.json").unwrap(); + } +} diff --git a/crates/apub/src/protocol/activities/voting/mod.rs b/crates/apub/src/protocol/activities/voting/mod.rs index ab405d0d8..94f759ed8 100644 --- a/crates/apub/src/protocol/activities/voting/mod.rs +++ b/crates/apub/src/protocol/activities/voting/mod.rs @@ -8,8 +8,8 @@ mod tests { tests::test_parse_lemmy_item, }; - #[actix_rt::test] - async fn test_parse_lemmy_voting() { + #[test] + fn test_parse_lemmy_voting() { test_parse_lemmy_item::("assets/lemmy/activities/voting/like_note.json").unwrap(); test_parse_lemmy_item::("assets/lemmy/activities/voting/dislike_page.json").unwrap(); diff --git a/crates/apub/src/protocol/activities/voting/undo_vote.rs b/crates/apub/src/protocol/activities/voting/undo_vote.rs index d3f4fb337..d8ba7cbae 100644 --- a/crates/apub/src/protocol/activities/voting/undo_vote.rs +++ b/crates/apub/src/protocol/activities/voting/undo_vote.rs @@ -19,6 +19,7 @@ pub struct UndoVote { #[serde(rename = "type")] pub(crate) kind: UndoType, pub(crate) id: Url, + #[serde(flatten)] pub(crate) unparsed: Unparsed, } diff --git a/crates/apub/src/protocol/activities/voting/vote.rs b/crates/apub/src/protocol/activities/voting/vote.rs index 2f07aea85..cafd6bbc3 100644 --- a/crates/apub/src/protocol/activities/voting/vote.rs +++ b/crates/apub/src/protocol/activities/voting/vote.rs @@ -22,6 +22,7 @@ pub struct Vote { #[serde(rename = "type")] pub(crate) kind: VoteType, pub(crate) id: Url, + #[serde(flatten)] pub(crate) unparsed: Unparsed, } diff --git a/crates/apub/src/protocol/collections/mod.rs b/crates/apub/src/protocol/collections/mod.rs index f34dd1d10..0e251a1bb 100644 --- a/crates/apub/src/protocol/collections/mod.rs +++ b/crates/apub/src/protocol/collections/mod.rs @@ -15,8 +15,8 @@ mod tests { tests::test_parse_lemmy_item, }; - #[actix_rt::test] - async fn test_parse_lemmy_collections() { + #[test] + fn test_parse_lemmy_collections() { test_parse_lemmy_item::("assets/lemmy/collections/group_followers.json") .unwrap(); let outbox = diff --git a/crates/apub/src/protocol/mod.rs b/crates/apub/src/protocol/mod.rs index d1532a952..bb384de64 100644 --- a/crates/apub/src/protocol/mod.rs +++ b/crates/apub/src/protocol/mod.rs @@ -49,11 +49,21 @@ pub struct Unparsed(HashMap); #[cfg(test)] pub(crate) mod tests { - use crate::objects::tests::file_to_json_object; + use crate::context::WithContext; use assert_json_diff::assert_json_include; use lemmy_utils::LemmyError; use serde::{de::DeserializeOwned, Serialize}; - use std::collections::HashMap; + use std::{collections::HashMap, fs::File, io::BufReader}; + + pub(crate) fn file_to_json_object(path: &str) -> Result { + let file = File::open(path)?; + let reader = BufReader::new(file); + Ok(serde_json::from_reader(reader)?) + } + + pub(crate) fn test_json(path: &str) -> Result, LemmyError> { + file_to_json_object::>(path) + } /// Check that json deserialize -> serialize -> deserialize gives identical file as initial one. /// Ensures that there are no breaking changes in sent data. diff --git a/crates/apub/src/protocol/objects/chat_message.rs b/crates/apub/src/protocol/objects/chat_message.rs index 608300ce1..a39f7b250 100644 --- a/crates/apub/src/protocol/objects/chat_message.rs +++ b/crates/apub/src/protocol/objects/chat_message.rs @@ -1,6 +1,6 @@ use crate::{ objects::{person::ApubPerson, private_message::ApubPrivateMessage}, - protocol::{Source, Unparsed}, + protocol::Source, }; use chrono::{DateTime, FixedOffset}; use lemmy_apub_lib::{object_id::ObjectId, values::MediaTypeHtml}; @@ -17,12 +17,11 @@ pub struct ChatMessage { #[serde(deserialize_with = "crate::deserialize_one")] pub(crate) to: [ObjectId; 1], pub(crate) content: String, + pub(crate) media_type: Option, pub(crate) source: Option, pub(crate) published: Option>, pub(crate) updated: Option>, - #[serde(flatten)] - pub(crate) unparsed: Unparsed, } /// https://docs.pleroma.social/backend/development/ap_extensions/#chatmessages diff --git a/crates/apub/src/protocol/objects/group.rs b/crates/apub/src/protocol/objects/group.rs index 5a2d39453..51e3a00ac 100644 --- a/crates/apub/src/protocol/objects/group.rs +++ b/crates/apub/src/protocol/objects/group.rs @@ -5,7 +5,7 @@ use crate::{ community_outbox::ApubCommunityOutbox, }, objects::{community::ApubCommunity, get_summary_from_string_or_source}, - protocol::{objects::Endpoints, ImageObject, Source, Unparsed}, + protocol::{objects::Endpoints, ImageObject, Source}, }; use activitystreams_kinds::actor::GroupType; use chrono::{DateTime, FixedOffset}; @@ -27,10 +27,14 @@ pub struct Group { #[serde(rename = "type")] pub(crate) kind: GroupType, pub(crate) id: ObjectId, - /// username, set at account creation and can never be changed + /// username, set at account creation and usually fixed after that pub(crate) preferred_username: String, - /// title (can be changed at any time) + /// displayname pub(crate) name: String, + pub(crate) inbox: Url, + pub(crate) followers: Url, + pub(crate) public_key: PublicKey, + pub(crate) summary: Option, pub(crate) source: Option, pub(crate) icon: Option, @@ -40,15 +44,10 @@ pub struct Group { pub(crate) sensitive: Option, // lemmy extension pub(crate) moderators: Option>, - pub(crate) inbox: Url, pub(crate) outbox: ObjectId, - pub(crate) followers: Url, pub(crate) endpoints: Option, - pub(crate) public_key: PublicKey, pub(crate) published: Option>, pub(crate) updated: Option>, - #[serde(flatten)] - pub(crate) unparsed: Unparsed, } impl Group { diff --git a/crates/apub/src/protocol/objects/instance.rs b/crates/apub/src/protocol/objects/instance.rs index 2a967ac52..c70a780f4 100644 --- a/crates/apub/src/protocol/objects/instance.rs +++ b/crates/apub/src/protocol/objects/instance.rs @@ -1,6 +1,6 @@ use crate::{ objects::instance::ApubSite, - protocol::{ImageObject, Source, Unparsed}, + protocol::{ImageObject, Source}, }; use activitystreams_kinds::actor::ServiceType; use chrono::{DateTime, FixedOffset}; @@ -18,6 +18,11 @@ pub struct Instance { pub(crate) id: ObjectId, // site name pub(crate) name: String, + pub(crate) inbox: Url, + /// mandatory field in activitypub, lemmy currently serves an empty outbox + pub(crate) outbox: Url, + pub(crate) public_key: PublicKey, + // sidebar pub(crate) content: Option, pub(crate) source: Option, @@ -28,12 +33,6 @@ pub struct Instance { pub(crate) icon: Option, /// instance banner pub(crate) image: Option, - pub(crate) inbox: Url, - /// mandatory field in activitypub, currently empty in lemmy - pub(crate) outbox: Url, - pub(crate) public_key: PublicKey, pub(crate) published: DateTime, pub(crate) updated: Option>, - #[serde(flatten)] - pub(crate) unparsed: Unparsed, } diff --git a/crates/apub/src/protocol/objects/mod.rs b/crates/apub/src/protocol/objects/mod.rs index 20aaca181..dfe502f3a 100644 --- a/crates/apub/src/protocol/objects/mod.rs +++ b/crates/apub/src/protocol/objects/mod.rs @@ -17,25 +17,21 @@ pub struct Endpoints { #[cfg(test)] mod tests { - use crate::{ - context::WithContext, - objects::tests::file_to_json_object, - protocol::{ - objects::{ - chat_message::ChatMessage, - group::Group, - instance::Instance, - note::Note, - page::Page, - person::Person, - tombstone::Tombstone, - }, - tests::test_parse_lemmy_item, + use crate::protocol::{ + objects::{ + chat_message::ChatMessage, + group::Group, + instance::Instance, + note::Note, + page::Page, + person::Person, + tombstone::Tombstone, }, + tests::{test_json, test_parse_lemmy_item}, }; - #[actix_rt::test] - async fn test_parse_objects_lemmy() { + #[test] + fn test_parse_objects_lemmy() { test_parse_lemmy_item::("assets/lemmy/objects/instance.json").unwrap(); test_parse_lemmy_item::("assets/lemmy/objects/group.json").unwrap(); test_parse_lemmy_item::("assets/lemmy/objects/person.json").unwrap(); @@ -45,38 +41,37 @@ mod tests { test_parse_lemmy_item::("assets/lemmy/objects/tombstone.json").unwrap(); } - #[actix_rt::test] - async fn test_parse_objects_pleroma() { - file_to_json_object::>("assets/pleroma/objects/person.json").unwrap(); - file_to_json_object::>("assets/pleroma/objects/note.json").unwrap(); - file_to_json_object::>("assets/pleroma/objects/chat_message.json") - .unwrap(); + #[test] + fn test_parse_objects_pleroma() { + test_json::("assets/pleroma/objects/person.json").unwrap(); + test_json::("assets/pleroma/objects/note.json").unwrap(); + test_json::("assets/pleroma/objects/chat_message.json").unwrap(); } - #[actix_rt::test] - async fn test_parse_objects_smithereen() { - file_to_json_object::>("assets/smithereen/objects/person.json").unwrap(); - file_to_json_object::("assets/smithereen/objects/note.json").unwrap(); + #[test] + fn test_parse_objects_smithereen() { + test_json::("assets/smithereen/objects/person.json").unwrap(); + test_json::("assets/smithereen/objects/note.json").unwrap(); } - #[actix_rt::test] - async fn test_parse_objects_mastodon() { - file_to_json_object::>("assets/mastodon/objects/person.json").unwrap(); - file_to_json_object::>("assets/mastodon/objects/note.json").unwrap(); + #[test] + fn test_parse_objects_mastodon() { + test_json::("assets/mastodon/objects/person.json").unwrap(); + test_json::("assets/mastodon/objects/note.json").unwrap(); } - #[actix_rt::test] - async fn test_parse_objects_lotide() { - file_to_json_object::>("assets/lotide/objects/group.json").unwrap(); - file_to_json_object::>("assets/lotide/objects/person.json").unwrap(); - file_to_json_object::>("assets/lotide/objects/note.json").unwrap(); - file_to_json_object::>("assets/lotide/objects/page.json").unwrap(); - file_to_json_object::>("assets/lotide/objects/tombstone.json").unwrap(); + #[test] + fn test_parse_objects_lotide() { + test_json::("assets/lotide/objects/group.json").unwrap(); + test_json::("assets/lotide/objects/person.json").unwrap(); + test_json::("assets/lotide/objects/note.json").unwrap(); + test_json::("assets/lotide/objects/page.json").unwrap(); + test_json::("assets/lotide/objects/tombstone.json").unwrap(); } - #[actix_rt::test] - async fn test_parse_object_friendica() { - file_to_json_object::>("assets/friendica/objects/person.json").unwrap(); - file_to_json_object::>("assets/friendica/objects/note.json").unwrap(); + #[test] + fn test_parse_object_friendica() { + test_json::("assets/friendica/objects/person.json").unwrap(); + test_json::("assets/friendica/objects/note.json").unwrap(); } } diff --git a/crates/apub/src/protocol/objects/note.rs b/crates/apub/src/protocol/objects/note.rs index 73e4a1304..d5c61c1f8 100644 --- a/crates/apub/src/protocol/objects/note.rs +++ b/crates/apub/src/protocol/objects/note.rs @@ -2,7 +2,7 @@ use crate::{ fetcher::post_or_comment::PostOrComment, mentions::Mention, objects::{comment::ApubComment, person::ApubPerson, post::ApubPost}, - protocol::{Source, Unparsed}, + protocol::Source, }; use activitystreams_kinds::object::NoteType; use chrono::{DateTime, FixedOffset}; @@ -30,16 +30,15 @@ pub struct Note { #[serde(deserialize_with = "crate::deserialize_one_or_many")] pub(crate) cc: Vec, pub(crate) content: String, + pub(crate) in_reply_to: ObjectId, + pub(crate) media_type: Option, #[serde(default)] pub(crate) source: SourceCompat, - pub(crate) in_reply_to: ObjectId, pub(crate) published: Option>, pub(crate) updated: Option>, #[serde(default)] pub(crate) tag: Vec, - #[serde(flatten)] - pub(crate) unparsed: Unparsed, } /// Pleroma puts a raw string in the source, so we have to handle it here for deserialization to work diff --git a/crates/apub/src/protocol/objects/page.rs b/crates/apub/src/protocol/objects/page.rs index 08906e757..f6a282312 100644 --- a/crates/apub/src/protocol/objects/page.rs +++ b/crates/apub/src/protocol/objects/page.rs @@ -1,6 +1,6 @@ use crate::{ objects::{community::ApubCommunity, person::ApubPerson, post::ApubPost}, - protocol::{ImageObject, Source, Unparsed}, + protocol::{ImageObject, Source}, }; use chrono::{DateTime, FixedOffset}; use lemmy_apub_lib::{ @@ -30,10 +30,11 @@ pub struct Page { pub(crate) attributed_to: ObjectId, #[serde(deserialize_with = "crate::deserialize_one_or_many")] pub(crate) to: Vec, + pub(crate) name: String, + #[serde(default)] #[serde(deserialize_with = "crate::deserialize_one_or_many")] pub(crate) cc: Vec, - pub(crate) name: String, pub(crate) content: Option, pub(crate) media_type: Option, pub(crate) source: Option, @@ -44,8 +45,6 @@ pub struct Page { pub(crate) stickied: Option, pub(crate) published: Option>, pub(crate) updated: Option>, - #[serde(flatten)] - pub(crate) unparsed: Unparsed, } impl Page { diff --git a/crates/apub/src/protocol/objects/person.rs b/crates/apub/src/protocol/objects/person.rs index e254ed078..0ab359dfd 100644 --- a/crates/apub/src/protocol/objects/person.rs +++ b/crates/apub/src/protocol/objects/person.rs @@ -1,6 +1,6 @@ use crate::{ objects::person::ApubPerson, - protocol::{objects::Endpoints, ImageObject, Source, Unparsed}, + protocol::{objects::Endpoints, ImageObject, Source}, }; use chrono::{DateTime, FixedOffset}; use lemmy_apub_lib::{object_id::ObjectId, signatures::PublicKey}; @@ -21,9 +21,14 @@ pub struct Person { #[serde(rename = "type")] pub(crate) kind: UserTypes, pub(crate) id: ObjectId, - /// username, set at account creation and can never be changed + /// username, set at account creation and usually fixed after that pub(crate) preferred_username: String, - /// displayname (can be changed at any time) + pub(crate) inbox: Url, + /// mandatory field in activitypub, lemmy currently serves an empty outbox + pub(crate) outbox: Url, + pub(crate) public_key: PublicKey, + + /// displayname pub(crate) name: Option, pub(crate) summary: Option, pub(crate) source: Option, @@ -32,13 +37,7 @@ pub struct Person { /// user banner pub(crate) image: Option, pub(crate) matrix_user_id: Option, - pub(crate) inbox: Url, - /// mandatory field in activitypub, currently empty in lemmy - pub(crate) outbox: Url, pub(crate) endpoints: Option, - pub(crate) public_key: PublicKey, pub(crate) published: Option>, pub(crate) updated: Option>, - #[serde(flatten)] - pub(crate) unparsed: Unparsed, }