Add tests for parsing activities and collections

This commit is contained in:
Felix Ableitner 2021-11-01 14:05:20 +01:00
parent aaaf039779
commit 0bde2d595e
55 changed files with 1112 additions and 177 deletions

View file

@ -0,0 +1,13 @@
{
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": "http://ds9.lemmy.ml/u/lemmy_alpha",
"target": "http://enterprise.lemmy.ml/c/main/moderators",
"cc": [
"http://enterprise.lemmy.ml/c/main"
],
"type": "Add",
"id": "http://enterprise.lemmy.ml/activities/add/ec069147-77c3-447f-88c8-0ef1df10403f"
}

View file

@ -0,0 +1,37 @@
{
"actor": "http://enterprise.lemmy.ml/c/main",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"type": "Page",
"id": "http://enterprise.lemmy.ml/post/7",
"attributedTo": "http://enterprise.lemmy.ml/u/lemmy_beta",
"to": [
"http://enterprise.lemmy.ml/c/main",
"https://www.w3.org/ns/activitystreams#Public"
],
"name": "post 4",
"mediaType": "text/html",
"commentsEnabled": true,
"sensitive": false,
"stickied": false,
"published": "2021-11-01T12:11:22.871846+00:00"
},
"cc": [
"http://enterprise.lemmy.ml/c/main"
],
"type": "Create",
"id": "http://enterprise.lemmy.ml/activities/create/2807c9ec-3ad8-4859-a9e0-28b59b6e499f"
},
"cc": [
"http://enterprise.lemmy.ml/c/main/followers"
],
"type": "Announce",
"id": "http://enterprise.lemmy.ml/activities/announce/8030b171-803a-4108-94b1-342688f375cf"
}

View file

@ -0,0 +1,13 @@
{
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": "http://ds9.lemmy.ml/u/lemmy_alpha",
"cc": [
"http://enterprise.lemmy.ml/c/main"
],
"target": "http://enterprise.lemmy.ml/c/main",
"type": "Block",
"id": "http://enterprise.lemmy.ml/activities/block/5d42fffb-0903-4625-86d4-0b39bb344fc2"
}

View file

@ -0,0 +1,13 @@
{
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": "http://ds9.lemmy.ml/u/lemmy_alpha",
"cc": [
"http://enterprise.lemmy.ml/c/main"
],
"type": "Remove",
"target": "http://enterprise.lemmy.ml/c/main/moderators",
"id": "http://enterprise.lemmy.ml/activities/remove/aab114f8-cfbd-4935-a5b7-e1a64603650d"
}

View file

@ -0,0 +1,10 @@
{
"actor": "http://ds9.lemmy.ml/u/lemmy_alpha",
"to": [
"http://enterprise.lemmy.ml/c/main"
],
"object": "http://enterprise.lemmy.ml/post/7",
"summary": "report this post",
"type": "Flag",
"id": "http://ds9.lemmy.ml/activities/flag/98b0933f-5e45-4a95-a15f-e0dc86361ba4"
}

View file

@ -0,0 +1,24 @@
{
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": "http://ds9.lemmy.ml/u/lemmy_alpha",
"cc": [
"http://enterprise.lemmy.ml/c/main"
],
"target": "http://enterprise.lemmy.ml/c/main",
"type": "Block",
"id": "http://enterprise.lemmy.ml/activities/block/726f43ab-bd0e-4ab3-89c8-627e976f553c"
},
"cc": [
"http://enterprise.lemmy.ml/c/main"
],
"type": "Undo",
"id": "http://enterprise.lemmy.ml/activities/undo/06a20ffb-3e32-42fb-8f4c-674b36d7c557"
}

View file

@ -0,0 +1,37 @@
{
"actor": "http://ds9.lemmy.ml/u/lemmy_alpha",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"type": "Group",
"id": "http://enterprise.lemmy.ml/c/main",
"preferredUsername": "main",
"name": "The Updated Community",
"summary": "<p>updated 2</p>\n",
"source": {
"content": "updated 2",
"mediaType": "text/markdown"
},
"sensitive": false,
"moderators": "http://enterprise.lemmy.ml/c/main/moderators",
"inbox": "http://enterprise.lemmy.ml/c/main/inbox",
"outbox": "http://enterprise.lemmy.ml/c/main/outbox",
"followers": "http://enterprise.lemmy.ml/c/main/followers",
"endpoints": {
"sharedInbox": "http://enterprise.lemmy.ml/inbox"
},
"publicKey": {
"id": "http://enterprise.lemmy.ml/c/main#main-key",
"owner": "http://enterprise.lemmy.ml/c/main",
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA16Xh06V1l2yy0WAIMUTV\nnvZIuAuKDxzDQUNT+n8gmcVuvBu7tkpbPTQ3DjGB3bQfGC2ekew/yldwOXyZ7ry1\npbJSYSrCBJrAlPLs/ao3OPTqmcl3vnSWti/hqopEV+Um2t7fwpkCjVrnzVKRSlys\nihnrth64ZiwAqq2llpaXzWc1SR2URZYSdnry/4d9UNrZVkumIeg1gk9KbCAo4j/O\njsv/aBjpZcTeLmtMZf6fcrvGre9duJdx6e2Tg/YNcnSnARosqev/UwVTzzGNVWXg\n9rItaa0a0aea4se4Bn6QXvOBbcq3+OYZMR6a34hh5BTeNG8WbpwmVahS0WFUsv9G\nswIDAQAB\n-----END PUBLIC KEY-----\n"
},
"published": "2021-10-29T15:05:51.476984+00:00",
"updated": "2021-11-01T12:23:50.151874+00:00"
},
"cc": [
"http://enterprise.lemmy.ml/c/main"
],
"type": "Update",
"id": "http://ds9.lemmy.ml/activities/update/d3717cf5-096d-473f-9530-5d52f9d51f5f"
}

View file

@ -0,0 +1,29 @@
{
"actor": "http://ds9.lemmy.ml/u/lemmy_alpha",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"type": "Note",
"id": "http://ds9.lemmy.ml/comment/1",
"attributedTo": "http://ds9.lemmy.ml/u/lemmy_alpha",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"content": "hello",
"mediaType": "text/html",
"source": {
"content": "hello",
"mediaType": "text/markdown"
},
"inReplyTo": "http://ds9.lemmy.ml/post/1",
"published": "2021-11-01T11:45:49.794920+00:00"
},
"cc": [
"http://enterprise.lemmy.ml/c/main",
"http://ds9.lemmy.ml/u/lemmy_alpha"
],
"tag": [],
"type": "Create",
"id": "http://ds9.lemmy.ml/activities/create/1e77d67c-44ac-45ed-bf2a-460e21f60236"
}

View file

@ -0,0 +1,32 @@
{
"actor": "http://ds9.lemmy.ml/u/lemmy_alpha",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"type": "Page",
"id": "http://ds9.lemmy.ml/post/1",
"attributedTo": "http://ds9.lemmy.ml/u/lemmy_alpha",
"to": [
"http://enterprise.lemmy.ml/c/main",
"https://www.w3.org/ns/activitystreams#Public"
],
"name": "test post",
"content": "<p>test body</p>\n",
"mediaType": "text/html",
"source": {
"content": "test body",
"mediaType": "text/markdown"
},
"url": "https://lemmy.ml/pictrs/image/xl8W7FZfk9.jpg",
"commentsEnabled": true,
"sensitive": false,
"stickied": false,
"published": "2021-10-29T15:10:51.557399+00:00"
},
"cc": [
"http://enterprise.lemmy.ml/c/main"
],
"type": "Create",
"id": "http://ds9.lemmy.ml/activities/create/eee6a57a-622f-464d-b560-73ae1fcd3ddf"
}

View file

@ -0,0 +1,33 @@
{
"actor": "http://ds9.lemmy.ml/u/lemmy_alpha",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"type": "Page",
"id": "http://ds9.lemmy.ml/post/1",
"attributedTo": "http://ds9.lemmy.ml/u/lemmy_alpha",
"to": [
"http://enterprise.lemmy.ml/c/main",
"https://www.w3.org/ns/activitystreams#Public"
],
"name": "test post 1",
"content": "<p>test body</p>\n",
"mediaType": "text/html",
"source": {
"content": "test body",
"mediaType": "text/markdown"
},
"url": "https://lemmy.ml/pictrs/image/xl8W7FZfk9.jpg",
"commentsEnabled": true,
"sensitive": false,
"stickied": false,
"published": "2021-10-29T15:10:51.557399+00:00",
"updated": "2021-10-29T15:11:35.976374+00:00"
},
"cc": [
"http://enterprise.lemmy.ml/c/main"
],
"type": "Update",
"id": "http://ds9.lemmy.ml/activities/update/ab360117-e165-4de4-b7fc-906b62c98631"
}

View file

@ -0,0 +1,12 @@
{
"actor": "http://ds9.lemmy.ml/u/lemmy_alpha",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": "http://ds9.lemmy.ml/post/1",
"cc": [
"http://enterprise.lemmy.ml/c/main"
],
"type": "Delete",
"id": "http://ds9.lemmy.ml/activities/delete/f2abee48-c7bb-41d5-9e27-8775ff32db12"
}

View file

@ -0,0 +1,13 @@
{
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": "http://ds9.lemmy.ml/comment/1",
"cc": [
"http://enterprise.lemmy.ml/c/main"
],
"type": "Delete",
"summary": "bad comment",
"id": "http://enterprise.lemmy.ml/activities/delete/42ca1a79-f99e-4518-a2ca-ba2df221eb5e"
}

View file

@ -0,0 +1,23 @@
{
"actor": "http://ds9.lemmy.ml/u/lemmy_alpha",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"actor": "http://ds9.lemmy.ml/u/lemmy_alpha",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": "http://ds9.lemmy.ml/post/1",
"cc": [
"http://enterprise.lemmy.ml/c/main"
],
"type": "Delete",
"id": "http://ds9.lemmy.ml/activities/delete/b13cca96-7737-41e1-9769-8fbf972b3509"
},
"cc": [
"http://enterprise.lemmy.ml/c/main"
],
"type": "Undo",
"id": "http://ds9.lemmy.ml/activities/undo/5e939cfb-b8a1-4de8-950f-9d684e9162b9"
}

View file

@ -0,0 +1,24 @@
{
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": "http://ds9.lemmy.ml/comment/1",
"cc": [
"http://enterprise.lemmy.ml/c/main"
],
"type": "Delete",
"summary": "bad comment",
"id": "http://enterprise.lemmy.ml/activities/delete/2598435c-87a3-49cd-81f3-a44b03b7af9d"
},
"cc": [
"http://enterprise.lemmy.ml/c/main"
],
"type": "Undo",
"id": "http://enterprise.lemmy.ml/activities/undo/a850cf21-3866-4b3a-b80b-56aa00997fee"
}

View file

@ -0,0 +1,17 @@
{
"actor": "http://enterprise.lemmy.ml/c/main",
"to": [
"http://ds9.lemmy.ml/u/lemmy_alpha"
],
"object": {
"actor": "http://ds9.lemmy.ml/u/lemmy_alpha",
"to": [
"http://enterprise.lemmy.ml/c/main"
],
"object": "http://enterprise.lemmy.ml/c/main",
"type": "Follow",
"id": "http://ds9.lemmy.ml/activities/follow/6abcd50b-b8ca-4952-86b0-a6dd8cc12866"
},
"type": "Accept",
"id": "http://enterprise.lemmy.ml/activities/accept/75f080cc-3d45-4654-8186-8f3bb853fa27"
}

View file

@ -0,0 +1,9 @@
{
"actor": "http://ds9.lemmy.ml/u/lemmy_alpha",
"to": [
"http://enterprise.lemmy.ml/c/main"
],
"object": "http://enterprise.lemmy.ml/c/main",
"type": "Follow",
"id": "http://ds9.lemmy.ml/activities/follow/6abcd50b-b8ca-4952-86b0-a6dd8cc12866"
}

View file

@ -0,0 +1,17 @@
{
"actor": "http://ds9.lemmy.ml/u/lemmy_alpha",
"to": [
"http://enterprise.lemmy.ml/c/main"
],
"object": {
"actor": "http://ds9.lemmy.ml/u/lemmy_alpha",
"to": [
"http://enterprise.lemmy.ml/c/main"
],
"object": "http://enterprise.lemmy.ml/c/main",
"type": "Follow",
"id": "http://ds9.lemmy.ml/activities/follow/dc2f1bc5-f3a0-4daa-a46b-428cbfbd023c"
},
"type": "Undo",
"id": "http://ds9.lemmy.ml/activities/undo/dd83c482-8ebd-4b6c-9008-c8373bd1a86a"
}

View file

@ -0,0 +1,23 @@
{
"id": "http://enterprise.lemmy.ml/activities/create/987d05fa-f637-46d7-85be-13d112bc269f",
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
"to": [
"http://ds9.lemmy.ml/u/lemmy_alpha"
],
"object": {
"type": "ChatMessage",
"id": "http://enterprise.lemmy.ml/private_message/1",
"attributedTo": "http://enterprise.lemmy.ml/u/lemmy_beta",
"to": [
"http://ds9.lemmy.ml/u/lemmy_alpha"
],
"content": "hello",
"mediaType": "text/html",
"source": {
"content": "hello",
"mediaType": "text/markdown"
},
"published": "2021-10-29T15:31:56.058289+00:00"
},
"type": "Create"
}

View file

@ -0,0 +1,9 @@
{
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
"to": [
"http://enterprise.lemmy.ml/u/lemmy_beta"
],
"object": "http://enterprise.lemmy.ml/private_message/1",
"type": "Delete",
"id": "http://enterprise.lemmy.ml/activities/delete/041d9858-5eef-4ad9-84ae-7455b4d87ed9"
}

View file

@ -0,0 +1,17 @@
{
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
"to": [
"http://ds9.lemmy.ml/u/lemmy_alpha"
],
"object": {
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
"to": [
"http://enterprise.lemmy.ml/u/lemmy_beta"
],
"object": "http://enterprise.lemmy.ml/private_message/1",
"type": "Delete",
"id": "http://enterprise.lemmy.ml/activities/delete/616c41be-04ed-4bd4-b865-30712186b122"
},
"type": "Undo",
"id": "http://enterprise.lemmy.ml/activities/undo/35e5b337-014c-4bbe-8d63-6fac96f51409"
}

View file

@ -0,0 +1,12 @@
{
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": "http://ds9.lemmy.ml/post/1",
"cc": [
"http://enterprise.lemmy.ml/c/main"
],
"type": "Dislike",
"id": "http://enterprise.lemmy.ml/activities/dislike/64d40d40-a829-43a5-8247-1fb595b3ca1c"
}

View file

@ -0,0 +1,12 @@
{
"actor": "http://ds9.lemmy.ml/u/lemmy_alpha",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": "http://ds9.lemmy.ml/comment/1",
"cc": [
"http://enterprise.lemmy.ml/c/main"
],
"type": "Like",
"id": "http://ds9.lemmy.ml/activities/like/fd61d070-7382-46a9-b2b7-6bb253732877"
}

View file

@ -0,0 +1,23 @@
{
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": "http://ds9.lemmy.ml/post/1",
"cc": [
"http://enterprise.lemmy.ml/c/main"
],
"type": "Like",
"id": "http://enterprise.lemmy.ml/activities/like/2227ab2c-79e2-4fca-a1d2-1d67dacf2457"
},
"cc": [
"http://enterprise.lemmy.ml/c/main"
],
"type": "Undo",
"id": "http://enterprise.lemmy.ml/activities/undo/6cc6fb71-39fe-49ea-9506-f0423b101e98"
}

View file

@ -0,0 +1,23 @@
{
"actor": "http://ds9.lemmy.ml/u/lemmy_alpha",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"actor": "http://ds9.lemmy.ml/u/lemmy_alpha",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": "http://ds9.lemmy.ml/comment/1",
"cc": [
"http://enterprise.lemmy.ml/c/main"
],
"type": "Like",
"id": "http://ds9.lemmy.ml/activities/like/efcf7ae2-dfcc-4ff4-9ce4-6adf251ff004"
},
"cc": [
"http://enterprise.lemmy.ml/c/main"
],
"type": "Undo",
"id": "http://ds9.lemmy.ml/activities/undo/3518565c-24a7-4d9e-8e0a-f7a2f45ac618"
}

View file

@ -0,0 +1,6 @@
{
"id": "http://enterprise.lemmy.ml/c/main/followers",
"type": "Collection",
"totalItems": 3,
"items": []
}

View file

@ -0,0 +1,7 @@
{
"type": "OrderedCollection",
"id": "https://enterprise.lemmy.ml/c/tenforward/moderators",
"orderedItems": [
"https://enterprise.lemmy.ml/u/picard"
]
}

View file

@ -0,0 +1,209 @@
{
"type": "OrderedCollection",
"id": "https://ds9.lemmy.ml/c/main/outbox",
"totalItems": 7,
"orderedItems": [
{
"actor": "https://ds9.lemmy.ml/u/dess_ds9",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"type": "Page",
"id": "https://ds9.lemmy.ml/post/1685",
"attributedTo": "https://ds9.lemmy.ml/u/dess_ds9",
"to": [
"https://ds9.lemmy.ml/c/main",
"https://www.w3.org/ns/activitystreams#Public"
],
"name": "Test post",
"mediaType": "text/html",
"commentsEnabled": true,
"sensitive": false,
"stickied": false,
"published": "2021-09-30T16:37:58.425718+00:00",
"updated": "2021-09-30T16:39:50.934055+00:00"
},
"cc": [
"https://ds9.lemmy.ml/c/main"
],
"type": "Create",
"id": "https://ds9.lemmy.ml/activities/create/157bc329-05cb-4dc3-ad9e-5110fde3f3aa"
},
{
"actor": "https://ds9.lemmy.ml/u/nutomic",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"type": "Page",
"id": "https://ds9.lemmy.ml/post/1665",
"attributedTo": "https://ds9.lemmy.ml/u/nutomic",
"to": [
"https://ds9.lemmy.ml/c/main",
"https://www.w3.org/ns/activitystreams#Public"
],
"name": "another webmention test",
"mediaType": "text/html",
"url": "https://webmention.rocks/test/1",
"commentsEnabled": true,
"sensitive": false,
"stickied": false,
"published": "2021-09-17T13:22:15.026912+00:00"
},
"cc": [
"https://ds9.lemmy.ml/c/main"
],
"type": "Create",
"id": "https://ds9.lemmy.ml/activities/create/c54e4509-16ac-42bf-b3b4-0bf8516f8152"
},
{
"actor": "https://ds9.lemmy.ml/u/nutomic",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"type": "Page",
"id": "https://ds9.lemmy.ml/post/1664",
"attributedTo": "https://ds9.lemmy.ml/u/nutomic",
"to": [
"https://ds9.lemmy.ml/c/main",
"https://www.w3.org/ns/activitystreams#Public"
],
"name": "another test",
"mediaType": "text/html",
"url": "https://webmention.rocks/test/1",
"commentsEnabled": true,
"sensitive": false,
"stickied": false,
"published": "2021-09-17T13:13:21.675891+00:00"
},
"cc": [
"https://ds9.lemmy.ml/c/main"
],
"type": "Create",
"id": "https://ds9.lemmy.ml/activities/create/25f7d2cb-11d5-4c9c-aa3c-85fbff9f9e0c"
},
{
"actor": "https://ds9.lemmy.ml/u/nutomic",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"type": "Page",
"id": "https://ds9.lemmy.ml/post/1663",
"attributedTo": "https://ds9.lemmy.ml/u/nutomic",
"to": [
"https://ds9.lemmy.ml/c/main",
"https://www.w3.org/ns/activitystreams#Public"
],
"name": "Webmention test from Lemmy",
"mediaType": "text/html",
"url": "https://webmention.rocks/test/1",
"commentsEnabled": true,
"sensitive": false,
"stickied": false,
"published": "2021-09-17T13:00:15.392844+00:00"
},
"cc": [
"https://ds9.lemmy.ml/c/main"
],
"type": "Create",
"id": "https://ds9.lemmy.ml/activities/create/cfbd12b8-2e11-42b6-a609-b482decbaf11"
},
{
"actor": "https://ds9.lemmy.ml/u/dess_tester_3",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"type": "Page",
"id": "https://ds9.lemmy.ml/post/1644",
"attributedTo": "https://ds9.lemmy.ml/u/dess_tester_3",
"to": [
"https://ds9.lemmy.ml/c/main",
"https://www.w3.org/ns/activitystreams#Public"
],
"name": "The best wireless earbuds you can buy right now | Engadget",
"mediaType": "text/html",
"url": "https://www.engadget.com/best-wireless-earbuds-120058222.html",
"image": {
"type": "Image",
"url": "https://ds9.lemmy.ml/pictrs/image/0WWsYOuwAE.jpg"
},
"commentsEnabled": true,
"sensitive": false,
"stickied": false,
"published": "2021-08-26T01:22:06.428368+00:00"
},
"cc": [
"https://ds9.lemmy.ml/c/main"
],
"type": "Create",
"id": "https://ds9.lemmy.ml/activities/create/76c94408-944a-4a2f-a88b-d10f12b472b0"
},
{
"actor": "https://ds9.lemmy.ml/u/dess_ds9",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"type": "Page",
"id": "https://ds9.lemmy.ml/post/1643",
"attributedTo": "https://ds9.lemmy.ml/u/dess_ds9",
"to": [
"https://ds9.lemmy.ml/c/main",
"https://www.w3.org/ns/activitystreams#Public"
],
"name": "First Look: Cadillacs luxury EV debut seems like a winner | Engadges",
"content": "<p>test</p>\n",
"mediaType": "text/html",
"source": {
"content": "test",
"mediaType": "text/markdown"
},
"url": "https://www.engadget.com/cadillac-lyriq-luxury-ev-first-look-video-171543752.html",
"image": {
"type": "Image",
"url": "https://ds9.lemmy.ml/pictrs/image/gnmtvgXP31.jpg"
},
"commentsEnabled": true,
"sensitive": false,
"stickied": false,
"published": "2021-08-23T23:43:06.560543+00:00",
"updated": "2021-08-23T23:52:51.832606+00:00"
},
"cc": [
"https://ds9.lemmy.ml/c/main"
],
"type": "Create",
"id": "https://ds9.lemmy.ml/activities/create/b1f95918-f593-4951-91cf-2c3340cd9509"
},
{
"actor": "https://ds9.lemmy.ml/u/dess_ds9_2",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"object": {
"type": "Page",
"id": "https://ds9.lemmy.ml/post/1642",
"attributedTo": "https://ds9.lemmy.ml/u/dess_ds9_2",
"to": [
"https://ds9.lemmy.ml/c/main",
"https://www.w3.org/ns/activitystreams#Public"
],
"name": "A test post from DS9",
"mediaType": "text/html",
"commentsEnabled": true,
"sensitive": false,
"stickied": false,
"published": "2021-08-06T14:10:47.493075+00:00"
},
"cc": [
"https://ds9.lemmy.ml/c/main"
],
"type": "Create",
"id": "https://ds9.lemmy.ml/activities/create/6359b2e7-badb-4241-b5ee-b093078361bd"
}
]
}

View file

@ -0,0 +1,6 @@
{
"type": "OrderedCollection",
"id": "http://ds9.lemmy.ml/u/lemmy_alpha/outbox",
"orderedItems": [],
"totalItems": 0
}

View file

@ -13,6 +13,11 @@
"content": "This is a post in the /c/tenforward community",
"mediaType": "text/markdown"
},
"url": "https://enterprise.lemmy.ml/pictrs/image/eOtYb9iEiB.png",
"image": {
"type": "Image",
"url": "https://enterprise.lemmy.ml/pictrs/image/eOtYb9iEiB.png"
},
"sensitive": false,
"commentsEnabled": true,
"stickied": true,

View file

@ -16,6 +16,7 @@
"type": "Image",
"url": "https://enterprise.lemmy.ml/pictrs/image/XenaYI5hTn.png"
},
"matrix_user_id": "@picard:matrix.org",
"inbox": "https://enterprise.lemmy.ml/u/picard/inbox",
"outbox": "https://enterprise.lemmy.ml/u/picard/outbox",
"endpoints": {

View file

@ -128,16 +128,3 @@ impl GetCommunity for CreateOrUpdateComment {
Ok(community.into())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::objects::tests::file_to_json_object;
use serial_test::serial;
#[actix_rt::test]
#[serial]
async fn test_parse_pleroma_create_comment() {
file_to_json_object::<CreateOrUpdateComment>("assets/pleroma/activities/create-note.json");
}
}

View file

@ -1,12 +1,3 @@
use serde::{Deserialize, Serialize};
use lemmy_apub_lib::{
traits::{ActivityFields, ActivityHandler, ActorType},
verify::verify_urls_match,
};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use crate::{
activities::community::announce::GetCommunity,
objects::community::ApubCommunity,
@ -35,6 +26,10 @@ use crate::{
voting::{undo_vote::UndoVote, vote::Vote},
},
};
use lemmy_apub_lib::traits::{ActivityFields, ActivityHandler};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler, ActivityFields)]
#[serde(untagged)]
@ -107,7 +102,6 @@ impl GetCommunity for AnnouncableActivities {
AddMod(a) => a.get_community(context, request_counter).await?,
RemoveMod(a) => a.get_community(context, request_counter).await?,
};
verify_urls_match(self.actor(), &community.actor_id())?;
Ok(community)
}
}

View file

@ -120,3 +120,74 @@ impl ApubObject for ApubCommunityModerators {
Ok(ApubCommunityModerators { 0: vec![] })
}
}
#[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 lemmy_db_schema::{
source::{
community::Community,
person::{Person, PersonForm},
},
traits::Crud,
};
use serial_test::serial;
#[actix_rt::test]
#[serial]
async fn test_parse_lemmy_community_moderators() {
let context = init_context();
let community = parse_lemmy_community(&context).await;
let community_id = community.id;
let old_mod = PersonForm {
name: "holly".into(),
..PersonForm::default()
};
let old_mod = Person::create(&context.pool().get().unwrap(), &old_mod).unwrap();
let community_moderator_form = CommunityModeratorForm {
community_id: community.id,
person_id: old_mod.id,
};
CommunityModerator::join(&context.pool().get().unwrap(), &community_moderator_form).unwrap();
let new_mod = parse_lemmy_person(&context).await;
let json: GroupModerators =
file_to_json_object("assets/lemmy/collections/group_moderators.json");
let url = Url::parse("https://enterprise.lemmy.ml/c/tenforward").unwrap();
let mut request_counter = 0;
let community_context = CommunityContext {
0: community,
1: context,
};
ApubCommunityModerators::from_apub(&json, &community_context, &url, &mut request_counter)
.await
.unwrap();
assert_eq!(request_counter, 0);
let current_moderators = blocking(community_context.1.pool(), move |conn| {
CommunityModeratorView::for_community(conn, community_id)
})
.await
.unwrap()
.unwrap();
assert_eq!(current_moderators.len(), 1);
assert_eq!(current_moderators[0].moderator.id, new_mod.id);
Person::delete(&*community_context.1.pool().get().unwrap(), old_mod.id).unwrap();
Person::delete(&*community_context.1.pool().get().unwrap(), new_mod.id).unwrap();
Community::delete(
&*community_context.1.pool().get().unwrap(),
community_context.0.id,
)
.unwrap();
}
}

View file

@ -18,13 +18,8 @@ use lemmy_websocket::LemmyContext;
use crate::{
fetcher::object_id::ObjectId,
objects::{
comment::ApubComment,
community::ApubCommunity,
person::{ApubPerson, Person},
post::ApubPost,
},
protocol::objects::{group::Group, note::Note, page::Page},
objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson, post::ApubPost},
protocol::objects::{group::Group, note::Note, page::Page, person::Person},
};
/// Attempt to parse the query as URL, and fetch an ActivityPub object from it.

View file

@ -18,15 +18,12 @@ use crate::{
objects::community::ApubCommunity,
protocol::{
activities::community::announce::AnnounceActivity,
collections::group_followers::CommunityFollowers,
collections::group_followers::GroupFollowers,
},
};
use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse};
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
traits::{ActivityFields, ActorType, ApubObject},
verify::verify_domains_match,
};
use lemmy_apub_lib::traits::{ActivityFields, ApubObject};
use lemmy_db_schema::source::community::Community;
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
@ -84,7 +81,6 @@ pub(in crate::http) async fn receive_group_inbox(
if let GroupInboxActivities::AnnouncableActivities(announcable) = activity {
let community = announcable.get_community(context, &mut 0).await?;
let actor_id = ObjectId::new(announcable.actor().clone());
verify_domains_match(&community.actor_id(), announcable.id_unchecked())?;
verify_person_in_community(&actor_id, &community, context, &mut 0).await?;
if community.local {
AnnounceActivity::send(announcable, &community, vec![], context).await?;
@ -103,7 +99,7 @@ pub(crate) async fn get_apub_community_followers(
Community::read_from_name(conn, &info.community_name)
})
.await??;
let followers = CommunityFollowers::new(community, &context).await?;
let followers = GroupFollowers::new(community, &context).await?;
Ok(create_apub_response(&followers))
}

View file

@ -8,7 +8,7 @@ use crate::{
receive_activity,
},
objects::person::ApubPerson,
protocol::collections::person_outbox::UserOutbox,
protocol::collections::person_outbox::PersonOutbox,
};
use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse};
use lemmy_api_common::blocking;
@ -74,6 +74,6 @@ pub(crate) async fn get_apub_person_outbox(
Person::find_by_name(conn, &info.user_name)
})
.await??;
let outbox = UserOutbox::new(person).await?;
let outbox = PersonOutbox::new(person).await?;
Ok(create_apub_response(&outbox))
}

View file

@ -188,26 +188,20 @@ impl ApubObject for ApubComment {
pub(crate) mod tests {
use super::*;
use crate::objects::{
community::ApubCommunity,
person::ApubPerson,
community::{tests::parse_lemmy_community, ApubCommunity},
person::{tests::parse_lemmy_person, ApubPerson},
post::ApubPost,
tests::{file_to_json_object, init_context},
};
use assert_json_diff::assert_json_include;
use serial_test::serial;
pub(crate) async fn prepare_comment_test(
async fn prepare_comment_test(
url: &Url,
context: &LemmyContext,
) -> (ApubPerson, ApubCommunity, ApubPost) {
let person_json = file_to_json_object("assets/lemmy/objects/person.json");
let person = ApubPerson::from_apub(&person_json, context, url, &mut 0)
.await
.unwrap();
let community_json = file_to_json_object("assets/lemmy/objects/group.json");
let community = ApubCommunity::from_apub(&community_json, context, url, &mut 0)
.await
.unwrap();
let person = parse_lemmy_person(context).await;
let community = parse_lemmy_community(context).await;
let post_json = file_to_json_object("assets/lemmy/objects/page.json");
let post = ApubPost::from_apub(&post_json, context, url, &mut 0)
.await

View file

@ -222,42 +222,39 @@ impl ApubCommunity {
}
#[cfg(test)]
mod tests {
pub(crate) mod tests {
use super::*;
use crate::objects::tests::{file_to_json_object, init_context};
use assert_json_diff::assert_json_include;
use lemmy_db_schema::traits::Crud;
use serial_test::serial;
#[actix_rt::test]
#[serial]
async fn test_parse_lemmy_community() {
let context = init_context();
pub(crate) async fn parse_lemmy_community(context: &LemmyContext) -> ApubCommunity {
let mut json: Group = file_to_json_object("assets/lemmy/objects/group.json");
let json_orig = json.clone();
// change these links so they dont fetch over the network
json.moderators = Some(ObjectId::new(
Url::parse("https://enterprise.lemmy.ml/c/tenforward/not_moderators").unwrap(),
));
json.moderators = None;
json.outbox =
ObjectId::new(Url::parse("https://enterprise.lemmy.ml/c/tenforward/not_outbox").unwrap());
let url = Url::parse("https://enterprise.lemmy.ml/c/tenforward").unwrap();
let mut request_counter = 0;
let community = ApubCommunity::from_apub(&json, &context, &url, &mut request_counter)
let community = ApubCommunity::from_apub(&json, context, &url, &mut request_counter)
.await
.unwrap();
// this makes two requests to the (intentionally) broken outbox/moderators collections
assert_eq!(request_counter, 1);
community
}
#[actix_rt::test]
#[serial]
async fn test_parse_lemmy_community() {
let context = init_context();
let community = parse_lemmy_community(&context).await;
assert_eq!(community.actor_id.clone().into_inner(), url);
assert_eq!(community.title, "Ten Forward");
assert!(community.public_key.is_some());
assert!(!community.local);
assert_eq!(community.description.as_ref().unwrap().len(), 132);
// this makes two requests to the (intentionally) broken outbox/moderators collections
assert_eq!(request_counter, 2);
let to_apub = community.to_apub(&context).await.unwrap();
assert_json_include!(actual: json_orig, expected: to_apub);
Community::delete(&*context.pool().get().unwrap(), community.id).unwrap();
}

View file

@ -2,13 +2,16 @@ use crate::{
check_is_apub_id_valid,
generate_outbox_url,
objects::get_summary_from_string_or_source,
protocol::{ImageObject, Source},
protocol::{
objects::person::{Person, UserTypes},
ImageObject,
Source,
},
};
use activitystreams::{actor::Endpoints, object::kind::ImageType, unparsed::Unparsed};
use chrono::{DateTime, FixedOffset, NaiveDateTime};
use activitystreams::{actor::Endpoints, object::kind::ImageType};
use chrono::NaiveDateTime;
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
signatures::PublicKey,
traits::{ActorType, ApubObject},
values::MediaTypeMarkdown,
verify::verify_domains_match,
@ -22,54 +25,9 @@ use lemmy_utils::{
LemmyError,
};
use lemmy_websocket::LemmyContext;
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
use std::ops::Deref;
use url::Url;
#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq)]
pub enum UserTypes {
Person,
Service,
}
#[skip_serializing_none]
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Person {
#[serde(rename = "type")]
kind: UserTypes,
id: Url,
/// username, set at account creation and can never be changed
preferred_username: String,
/// displayname (can be changed at any time)
name: Option<String>,
summary: Option<String>,
source: Option<Source>,
/// user avatar
icon: Option<ImageObject>,
/// user banner
image: Option<ImageObject>,
matrix_user_id: Option<String>,
inbox: Url,
/// mandatory field in activitypub, currently empty in lemmy
outbox: Url,
endpoints: Endpoints<Url>,
public_key: PublicKey,
published: Option<DateTime<FixedOffset>>,
updated: Option<DateTime<FixedOffset>>,
#[serde(flatten)]
unparsed: Unparsed,
}
// TODO: can generate this with a derive macro
impl Person {
pub(crate) fn id(&self, expected_domain: &Url) -> Result<&Url, LemmyError> {
verify_domains_match(&self.id, expected_domain)?;
Ok(&self.id)
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct ApubPerson(DbPerson);
@ -170,7 +128,8 @@ impl ApubObject for ApubPerson {
expected_domain: &Url,
_request_counter: &mut i32,
) -> Result<ApubPerson, LemmyError> {
let actor_id = Some(person.id(expected_domain)?.clone().into());
verify_domains_match(&person.id, expected_domain)?;
let actor_id = Some(person.id.clone().into());
let name = person.preferred_username.clone();
let display_name: Option<String> = person.name.clone();
let bio = get_summary_from_string_or_source(&person.summary, &person.source);
@ -245,33 +204,33 @@ impl ActorType for ApubPerson {
}
#[cfg(test)]
mod tests {
pub(crate) mod tests {
use super::*;
use crate::objects::tests::{file_to_json_object, init_context};
use assert_json_diff::assert_json_include;
use lemmy_db_schema::traits::Crud;
use serial_test::serial;
pub(crate) async fn parse_lemmy_person(context: &LemmyContext) -> ApubPerson {
let json = file_to_json_object("assets/lemmy/objects/person.json");
let url = Url::parse("https://enterprise.lemmy.ml/u/picard").unwrap();
let mut request_counter = 0;
let person = ApubPerson::from_apub(&json, context, &url, &mut request_counter)
.await
.unwrap();
assert_eq!(request_counter, 0);
person
}
#[actix_rt::test]
#[serial]
async fn test_parse_lemmy_person() {
let context = init_context();
let json = file_to_json_object("assets/lemmy/objects/person.json");
let url = Url::parse("https://enterprise.lemmy.ml/u/picard").unwrap();
let mut request_counter = 0;
let person = ApubPerson::from_apub(&json, &context, &url, &mut request_counter)
.await
.unwrap();
let person = parse_lemmy_person(&context).await;
assert_eq!(person.actor_id.clone().into_inner(), url);
assert_eq!(person.display_name, Some("Jean-Luc Picard".to_string()));
assert!(person.public_key.is_some());
assert!(!person.local);
assert_eq!(person.bio.as_ref().unwrap().len(), 39);
assert_eq!(request_counter, 0);
let to_apub = person.to_apub(&context).await.unwrap();
assert_json_include!(actual: json, expected: to_apub);
DbPerson::delete(&*context.pool().get().unwrap(), person.id).unwrap();
}

View file

@ -193,28 +193,22 @@ impl ApubObject for ApubPost {
mod tests {
use super::*;
use crate::objects::{
community::ApubCommunity,
person::ApubPerson,
community::tests::parse_lemmy_community,
person::tests::parse_lemmy_person,
post::ApubPost,
tests::{file_to_json_object, init_context},
};
use assert_json_diff::assert_json_include;
use serial_test::serial;
#[actix_rt::test]
#[serial]
async fn test_parse_lemmy_post() {
let context = init_context();
let url = Url::parse("https://enterprise.lemmy.ml/post/55143").unwrap();
let community_json = file_to_json_object("assets/lemmy/objects/group.json");
let community = ApubCommunity::from_apub(&community_json, &context, &url, &mut 0)
.await
.unwrap();
let person_json = file_to_json_object("assets/lemmy/objects/person.json");
let person = ApubPerson::from_apub(&person_json, &context, &url, &mut 0)
.await
.unwrap();
let community = parse_lemmy_community(&context).await;
let person = parse_lemmy_person(&context).await;
let json = file_to_json_object("assets/lemmy/objects/page.json");
let url = Url::parse("https://enterprise.lemmy.ml/post/55143").unwrap();
let mut request_counter = 0;
let post = ApubPost::from_apub(&json, &context, &url, &mut request_counter)
.await
@ -228,9 +222,6 @@ mod tests {
assert!(post.stickied);
assert_eq!(request_counter, 0);
let to_apub = post.to_apub(&context).await.unwrap();
assert_json_include!(actual: json, expected: to_apub);
Post::delete(&*context.pool().get().unwrap(), post.id).unwrap();
Person::delete(&*context.pool().get().unwrap(), person.id).unwrap();
Community::delete(&*context.pool().get().unwrap(), community.id).unwrap();

View file

@ -5,3 +5,44 @@ pub mod remove_mod;
pub mod report;
pub mod undo_block_user;
pub mod update;
#[cfg(test)]
mod tests {
use crate::protocol::{
activities::community::{
add_mod::AddMod,
block_user::BlockUserFromCommunity,
remove_mod::RemoveMod,
report::Report,
undo_block_user::UndoBlockUserFromCommunity,
update::UpdateCommunity,
},
tests::test_parse_lemmy_item,
};
use activitystreams::activity::Announce;
use serial_test::serial;
#[actix_rt::test]
#[serial]
async fn test_parse_lemmy_community() {
test_parse_lemmy_item::<Announce>(
"assets/lemmy/activities/community/announce_create_page.json",
);
test_parse_lemmy_item::<AddMod>("assets/lemmy/activities/community/add_mod.json");
test_parse_lemmy_item::<RemoveMod>("assets/lemmy/activities/community/remove_mod.json");
test_parse_lemmy_item::<BlockUserFromCommunity>(
"assets/lemmy/activities/community/block_user.json",
);
test_parse_lemmy_item::<UndoBlockUserFromCommunity>(
"assets/lemmy/activities/community/undo_block_user.json",
);
test_parse_lemmy_item::<UpdateCommunity>(
"assets/lemmy/activities/community/update_community.json",
);
test_parse_lemmy_item::<Report>("assets/lemmy/activities/community/report_page.json");
}
}

View file

@ -1,2 +1,34 @@
pub mod comment;
pub mod post;
#[cfg(test)]
mod tests {
use crate::{
objects::tests::file_to_json_object,
protocol::{
activities::create_or_update::{comment::CreateOrUpdateComment, post::CreateOrUpdatePost},
tests::test_parse_lemmy_item,
},
};
use serial_test::serial;
#[actix_rt::test]
#[serial]
async fn test_parse_lemmy_create_or_update() {
test_parse_lemmy_item::<CreateOrUpdatePost>(
"assets/lemmy/activities/create_or_update/create_page.json",
);
test_parse_lemmy_item::<CreateOrUpdatePost>(
"assets/lemmy/activities/create_or_update/update_page.json",
);
test_parse_lemmy_item::<CreateOrUpdateComment>(
"assets/lemmy/activities/create_or_update/create_note.json",
);
}
#[actix_rt::test]
#[serial]
async fn test_parse_pleroma_create_or_update() {
file_to_json_object::<CreateOrUpdateComment>("assets/pleroma/activities/create_note.json");
}
}

View file

@ -1,2 +1,21 @@
pub mod delete;
pub mod undo_delete;
#[cfg(test)]
mod tests {
use crate::protocol::{
activities::deletion::{delete::Delete, undo_delete::UndoDelete},
tests::test_parse_lemmy_item,
};
use serial_test::serial;
#[actix_rt::test]
#[serial]
async fn test_parse_lemmy_voting() {
test_parse_lemmy_item::<Delete>("assets/lemmy/activities/deletion/remove_note.json");
test_parse_lemmy_item::<Delete>("assets/lemmy/activities/deletion/delete_page.json");
test_parse_lemmy_item::<UndoDelete>("assets/lemmy/activities/deletion/undo_remove_note.json");
test_parse_lemmy_item::<UndoDelete>("assets/lemmy/activities/deletion/undo_delete_page.json");
}
}

View file

@ -1,3 +1,26 @@
pub(crate) mod accept;
pub mod follow;
pub mod undo_follow;
#[cfg(test)]
mod tests {
use crate::protocol::{
activities::following::{
accept::AcceptFollowCommunity,
follow::FollowCommunity,
undo_follow::UndoFollowCommunity,
},
tests::test_parse_lemmy_item,
};
use serial_test::serial;
#[actix_rt::test]
#[serial]
async fn test_parse_lemmy_accept_follow() {
test_parse_lemmy_item::<FollowCommunity>("assets/lemmy/activities/following/follow.json");
test_parse_lemmy_item::<AcceptFollowCommunity>("assets/lemmy/activities/following/accept.json");
test_parse_lemmy_item::<UndoFollowCommunity>(
"assets/lemmy/activities/following/undo_follow.json",
);
}
}

View file

@ -1,3 +1,30 @@
pub mod create_or_update;
pub mod delete;
pub mod undo_delete;
#[cfg(test)]
mod tests {
use crate::protocol::{
activities::private_message::{
create_or_update::CreateOrUpdatePrivateMessage,
delete::DeletePrivateMessage,
undo_delete::UndoDeletePrivateMessage,
},
tests::test_parse_lemmy_item,
};
use serial_test::serial;
#[actix_rt::test]
#[serial]
async fn test_parse_lemmy_private_message() {
test_parse_lemmy_item::<CreateOrUpdatePrivateMessage>(
"assets/lemmy/activities/private_message/create.json",
);
test_parse_lemmy_item::<DeletePrivateMessage>(
"assets/lemmy/activities/private_message/delete.json",
);
test_parse_lemmy_item::<UndoDeletePrivateMessage>(
"assets/lemmy/activities/private_message/undo_delete.json",
);
}
}

View file

@ -1,2 +1,21 @@
pub mod undo_vote;
pub mod vote;
#[cfg(test)]
mod tests {
use crate::protocol::{
activities::voting::{undo_vote::UndoVote, vote::Vote},
tests::test_parse_lemmy_item,
};
use serial_test::serial;
#[actix_rt::test]
#[serial]
async fn test_parse_lemmy_voting() {
test_parse_lemmy_item::<Vote>("assets/lemmy/activities/voting/like_note.json");
test_parse_lemmy_item::<Vote>("assets/lemmy/activities/voting/dislike_page.json");
test_parse_lemmy_item::<UndoVote>("assets/lemmy/activities/voting/undo_like_note.json");
test_parse_lemmy_item::<UndoVote>("assets/lemmy/activities/voting/undo_dislike_page.json");
}
}

View file

@ -10,25 +10,25 @@ use url::Url;
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct CommunityFollowers {
pub(crate) struct GroupFollowers {
id: Url,
r#type: CollectionType,
total_items: i32,
items: Vec<()>,
}
impl CommunityFollowers {
impl GroupFollowers {
pub(crate) async fn new(
community: Community,
context: &LemmyContext,
) -> Result<CommunityFollowers, LemmyError> {
) -> Result<GroupFollowers, LemmyError> {
let community_id = community.id;
let community_followers = blocking(context.pool(), move |conn| {
CommunityFollowerView::for_community(conn, community_id)
})
.await??;
Ok(CommunityFollowers {
Ok(GroupFollowers {
id: generate_followers_url(&community.actor_id)?.into_inner(),
r#type: CollectionType::Collection,
total_items: community_followers.len() as i32,

View file

@ -2,3 +2,27 @@ pub(crate) mod group_followers;
pub(crate) mod group_moderators;
pub(crate) mod group_outbox;
pub(crate) mod person_outbox;
#[cfg(test)]
mod tests {
use crate::protocol::{
collections::{
group_followers::GroupFollowers,
group_moderators::GroupModerators,
group_outbox::GroupOutbox,
person_outbox::PersonOutbox,
},
tests::test_parse_lemmy_item,
};
use serial_test::serial;
#[actix_rt::test]
#[serial]
async fn test_parse_lemmy_collections() {
test_parse_lemmy_item::<GroupFollowers>("assets/lemmy/collections/group_followers.json");
let outbox = test_parse_lemmy_item::<GroupOutbox>("assets/lemmy/collections/group_outbox.json");
assert_eq!(outbox.ordered_items.len() as i32, outbox.total_items);
test_parse_lemmy_item::<GroupModerators>("assets/lemmy/collections/group_moderators.json");
test_parse_lemmy_item::<PersonOutbox>("assets/lemmy/collections/person_outbox.json");
}
}

View file

@ -7,16 +7,16 @@ use url::Url;
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct UserOutbox {
pub(crate) struct PersonOutbox {
r#type: OrderedCollectionType,
id: Url,
ordered_items: Vec<()>,
total_items: i32,
}
impl UserOutbox {
pub(crate) async fn new(user: Person) -> Result<UserOutbox, LemmyError> {
Ok(UserOutbox {
impl PersonOutbox {
pub(crate) async fn new(user: Person) -> Result<PersonOutbox, LemmyError> {
Ok(PersonOutbox {
r#type: OrderedCollectionType::OrderedCollection,
id: generate_outbox_url(&user.actor_id)?.into_inner(),
ordered_items: vec![],

View file

@ -22,3 +22,20 @@ pub struct ImageObject {
pub(crate) kind: ImageType,
pub(crate) url: Url,
}
#[cfg(test)]
pub(crate) mod tests {
use crate::objects::tests::file_to_json_object;
use assert_json_diff::assert_json_include;
use serde::{de::DeserializeOwned, Serialize};
use std::collections::HashMap;
pub(crate) fn test_parse_lemmy_item<T: Serialize + DeserializeOwned>(path: &str) -> T {
let parsed = file_to_json_object::<T>(path);
// ensure that no field is ignored when parsing
let raw = file_to_json_object::<HashMap<String, serde_json::Value>>(path);
assert_json_include!(actual: &parsed, expected: raw);
parsed
}
}

View file

@ -2,4 +2,24 @@ pub(crate) mod chat_message;
pub(crate) mod group;
pub(crate) mod note;
pub(crate) mod page;
pub(crate) mod person;
pub(crate) mod tombstone;
#[cfg(test)]
mod tests {
use crate::protocol::{
objects::{chat_message::ChatMessage, group::Group, note::Note, page::Page, person::Person},
tests::test_parse_lemmy_item,
};
use serial_test::serial;
#[actix_rt::test]
#[serial]
async fn test_parse_lemmy_object() {
test_parse_lemmy_item::<Person>("assets/lemmy/objects/person.json");
test_parse_lemmy_item::<Group>("assets/lemmy/objects/group.json");
test_parse_lemmy_item::<Page>("assets/lemmy/objects/page.json");
test_parse_lemmy_item::<Note>("assets/lemmy/objects/note.json");
test_parse_lemmy_item::<ChatMessage>("assets/lemmy/objects/chat_message.json");
}
}

View file

@ -0,0 +1,41 @@
use crate::protocol::{ImageObject, Source};
use activitystreams::{actor::Endpoints, unparsed::Unparsed, url::Url};
use chrono::{DateTime, FixedOffset};
use lemmy_apub_lib::signatures::PublicKey;
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq)]
pub enum UserTypes {
Person,
Service,
}
#[skip_serializing_none]
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Person {
#[serde(rename = "type")]
pub(crate) kind: UserTypes,
pub(crate) id: Url,
/// username, set at account creation and can never be changed
pub(crate) preferred_username: String,
/// displayname (can be changed at any time)
pub(crate) name: Option<String>,
pub(crate) summary: Option<String>,
pub(crate) source: Option<Source>,
/// user avatar
pub(crate) icon: Option<ImageObject>,
/// user banner
pub(crate) image: Option<ImageObject>,
pub(crate) matrix_user_id: Option<String>,
pub(crate) inbox: Url,
/// mandatory field in activitypub, currently empty in lemmy
pub(crate) outbox: Url,
pub(crate) endpoints: Endpoints<Url>,
pub(crate) public_key: PublicKey,
pub(crate) published: Option<DateTime<FixedOffset>>,
pub(crate) updated: Option<DateTime<FixedOffset>>,
#[serde(flatten)]
pub(crate) unparsed: Unparsed,
}

View file

@ -1,7 +1,6 @@
use crate::{newtypes::DbUrl, source::activity::*, traits::Crud};
use diesel::{dsl::*, result::Error, sql_types::Text, *};
use diesel::{dsl::*, result::Error, *};
use serde::Serialize;
use serde_json::Value;
use std::{
fmt::Debug,
io::{Error as IoError, ErrorKind},
@ -75,26 +74,6 @@ impl Activity {
use crate::schema::activity::dsl::*;
diesel::delete(activity.filter(published.lt(now - 6.months()))).execute(conn)
}
pub fn read_community_outbox(
conn: &PgConnection,
community_actor_id: &DbUrl,
) -> Result<Vec<Value>, Error> {
use crate::schema::activity::dsl::*;
let res: Vec<Value> = activity
.select(data)
.filter(
sql("activity.data ->> 'type' = 'Announce'")
.sql(" AND activity.data -> 'object' ->> 'type' = 'Create'")
.sql(" AND activity.data -> 'object' -> 'object' ->> 'type' = 'Page'")
.sql(" AND activity.data ->> 'actor' = ")
.bind::<Text, _>(community_actor_id)
.sql(" ORDER BY activity.published DESC"),
)
.limit(20)
.get_results(conn)?;
Ok(res)
}
}
#[cfg(test)]

View file

@ -28,7 +28,7 @@ services:
- ./volumes/pictrs_alpha:/mnt
lemmy-alpha-ui:
image: dessalines/lemmy-ui:dev
image: dessalines/lemmy-ui:0.13.3
environment:
- LEMMY_INTERNAL_HOST=lemmy-alpha:8541
- LEMMY_EXTERNAL_HOST=localhost:8541
@ -57,7 +57,7 @@ services:
- ./volumes/postgres_alpha:/var/lib/postgresql/data
lemmy-beta-ui:
image: dessalines/lemmy-ui:dev
image: dessalines/lemmy-ui:0.13.3
environment:
- LEMMY_INTERNAL_HOST=lemmy-beta:8551
- LEMMY_EXTERNAL_HOST=localhost:8551