summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authortusooa <tusooa@kazv.moe>2023-10-15 20:48:16 +0000
committertusooa <tusooa@kazv.moe>2023-10-15 20:48:16 +0000
commit14b1b9c9b0cc3a799e8aa8ad1e54ec1b6b3243d8 (patch)
tree42f8d025607f9602f1a81a67f506ade936c9b684 /test
parenta94cf2ad4ff523f72d03a9bf76ca9ec6b242c79b (diff)
parent08608afca5566f712acdc14b7c43976d6d071106 (diff)
downloadpleroma-14b1b9c9b0cc3a799e8aa8ad1e54ec1b6b3243d8.tar.gz
pleroma-14b1b9c9b0cc3a799e8aa8ad1e54ec1b6b3243d8.zip
Merge branch 'tusooa/quote' into 'develop'
Quoting See merge request pleroma/pleroma!3921
Diffstat (limited to 'test')
-rw-r--r--test/fixtures/quote_post/fedibird_quote_mismatched.json54
-rw-r--r--test/fixtures/quote_post/fedibird_quote_post.json52
-rw-r--r--test/fixtures/quote_post/fedibird_quote_uri.json54
-rw-r--r--test/fixtures/quote_post/fep-e232-tag-example.json17
-rw-r--r--test/fixtures/quote_post/misskey_quote_post.json46
-rw-r--r--test/fixtures/tesla_mock/aimu@misskey.io.json64
-rw-r--r--test/fixtures/tesla_mock/misskey.io_8vs6wxufd0.json44
-rw-r--r--test/pleroma/web/activity_pub/builder_test.exs29
-rw-r--r--test/pleroma/web/activity_pub/mrf/inline_quote_policy_test.exs112
-rw-r--r--test/pleroma/web/activity_pub/mrf/quote_to_link_tag_policy_test.exs73
-rw-r--r--test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs49
-rw-r--r--test/pleroma/web/activity_pub/transmogrifier_test.exs41
-rw-r--r--test/pleroma/web/common_api/activity_draft_test.exs33
-rw-r--r--test/pleroma/web/common_api_test.exs47
-rw-r--r--test/pleroma/web/mastodon_api/controllers/status_controller_test.exs22
-rw-r--r--test/pleroma/web/mastodon_api/views/status_view_test.exs86
-rw-r--r--test/support/http_request_mock.ex18
17 files changed, 837 insertions, 4 deletions
diff --git a/test/fixtures/quote_post/fedibird_quote_mismatched.json b/test/fixtures/quote_post/fedibird_quote_mismatched.json
new file mode 100644
index 000000000..8dee5daff
--- /dev/null
+++ b/test/fixtures/quote_post/fedibird_quote_mismatched.json
@@ -0,0 +1,54 @@
+{
+ "@context": [
+ "https://www.w3.org/ns/activitystreams",
+ {
+ "ostatus": "http://ostatus.org#",
+ "atomUri": "ostatus:atomUri",
+ "inReplyToAtomUri": "ostatus:inReplyToAtomUri",
+ "conversation": "ostatus:conversation",
+ "sensitive": "as:sensitive",
+ "toot": "http://joinmastodon.org/ns#",
+ "votersCount": "toot:votersCount",
+ "fedibird": "http://fedibird.com/ns#",
+ "quoteUri": "fedibird:quoteUri",
+ "expiry": "fedibird:expiry"
+ }
+ ],
+ "id": "https://fedibird.com/users/noellabo/statuses/107712183700212249",
+ "type": "Note",
+ "summary": null,
+ "inReplyTo": null,
+ "published": "2022-01-30T15:44:50Z",
+ "url": "https://fedibird.com/@noellabo/107712183700212249",
+ "attributedTo": "https://fedibird.com/users/noellabo",
+ "to": [
+ "https://www.w3.org/ns/activitystreams#Public"
+ ],
+ "cc": [
+ "https://fedibird.com/users/noellabo/followers"
+ ],
+ "sensitive": false,
+ "atomUri": "https://fedibird.com/users/noellabo/statuses/107712183700212249",
+ "inReplyToAtomUri": null,
+ "conversation": "tag:fedibird.com,2022-01-30:objectId=107712183700170473:objectType=Conversation",
+ "context": "https://fedibird.com/contexts/107712183700170473",
+ "quoteUri": "https://unnerv.jp/users/UN_NERV/statuses/107712176849067434",
+ "_misskey_quote": "https://unnerv.jp/users/UN_NERV/statuses/107712176849067434",
+ "_misskey_content": "揺れていたようだ",
+ "content": "<p>揺れていたようだ<span class=\"quote-inline\"><br/>QT: <a class=\"status-url-link\" data-status-account-acct=\"UN_NERV@unnerv.jp\" data-status-id=\"107712177062934465\" href=\"https://unnerv.jp/@UN_NERV/107712176849067434\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">unnerv.jp/@UN_NERV/10771217684</span><span class=\"invisible\">9067434</span></a></span></p>",
+ "contentMap": {
+ "ja": "<p>揺れていたようだ<span class=\"quote-inline\"><br/>QT: <a class=\"status-url-link\" data-status-account-acct=\"UN_NERV@unnerv.jp\" data-status-id=\"107712177062934465\" href=\"https://unnerv.jp/@UN_NERV/107712176849067434\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">unnerv.jp/@UN_NERV/10771217684</span><span class=\"invisible\">9067434</span></a></span></p>"
+ },
+ "attachment": [],
+ "tag": [],
+ "replies": {
+ "id": "https://fedibird.com/users/noellabo/statuses/107712183700212249/replies",
+ "type": "Collection",
+ "first": {
+ "type": "CollectionPage",
+ "next": "https://fedibird.com/users/noellabo/statuses/107712183700212249/replies?only_other_accounts=true&page=true",
+ "partOf": "https://fedibird.com/users/noellabo/statuses/107712183700212249/replies",
+ "items": []
+ }
+ }
+}
diff --git a/test/fixtures/quote_post/fedibird_quote_post.json b/test/fixtures/quote_post/fedibird_quote_post.json
new file mode 100644
index 000000000..ebf383356
--- /dev/null
+++ b/test/fixtures/quote_post/fedibird_quote_post.json
@@ -0,0 +1,52 @@
+{
+ "@context": [
+ "https://www.w3.org/ns/activitystreams",
+ {
+ "ostatus": "http://ostatus.org#",
+ "atomUri": "ostatus:atomUri",
+ "inReplyToAtomUri": "ostatus:inReplyToAtomUri",
+ "conversation": "ostatus:conversation",
+ "sensitive": "as:sensitive",
+ "toot": "http://joinmastodon.org/ns#",
+ "votersCount": "toot:votersCount",
+ "expiry": "toot:expiry"
+ }
+ ],
+ "id": "https://fedibird.com/users/noellabo/statuses/107663670404015196",
+ "type": "Note",
+ "summary": null,
+ "inReplyTo": null,
+ "published": "2022-01-22T02:07:16Z",
+ "url": "https://fedibird.com/@noellabo/107663670404015196",
+ "attributedTo": "https://fedibird.com/users/noellabo",
+ "to": [
+ "https://www.w3.org/ns/activitystreams#Public"
+ ],
+ "cc": [
+ "https://fedibird.com/users/noellabo/followers"
+ ],
+ "sensitive": false,
+ "atomUri": "https://fedibird.com/users/noellabo/statuses/107663670404015196",
+ "inReplyToAtomUri": null,
+ "conversation": "tag:fedibird.com,2022-01-22:objectId=107663670404038002:objectType=Conversation",
+ "context": "https://fedibird.com/contexts/107663670404038002",
+ "quoteURL": "https://misskey.io/notes/8vsn2izjwh",
+ "_misskey_quote": "https://misskey.io/notes/8vsn2izjwh",
+ "_misskey_content": "いつの生まれだシトリン",
+ "content": "<p>いつの生まれだシトリン<span class=\"quote-inline\"><br/>QT: <a class=\"status-url-link\" data-status-account-acct=\"Citrine@misskey.io\" data-status-id=\"107663207194225003\" href=\"https://misskey.io/notes/8vsn2izjwh\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"\">misskey.io/notes/8vsn2izjwh</span><span class=\"invisible\"></span></a></span></p>",
+ "contentMap": {
+ "ja": "<p>いつの生まれだシトリン<span class=\"quote-inline\"><br/>QT: <a class=\"status-url-link\" data-status-account-acct=\"Citrine@misskey.io\" data-status-id=\"107663207194225003\" href=\"https://misskey.io/notes/8vsn2izjwh\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"\">misskey.io/notes/8vsn2izjwh</span><span class=\"invisible\"></span></a></span></p>"
+ },
+ "attachment": [],
+ "tag": [],
+ "replies": {
+ "id": "https://fedibird.com/users/noellabo/statuses/107663670404015196/replies",
+ "type": "Collection",
+ "first": {
+ "type": "CollectionPage",
+ "next": "https://fedibird.com/users/noellabo/statuses/107663670404015196/replies?only_other_accounts=true&page=true",
+ "partOf": "https://fedibird.com/users/noellabo/statuses/107663670404015196/replies",
+ "items": []
+ }
+ }
+}
diff --git a/test/fixtures/quote_post/fedibird_quote_uri.json b/test/fixtures/quote_post/fedibird_quote_uri.json
new file mode 100644
index 000000000..7c328fdb9
--- /dev/null
+++ b/test/fixtures/quote_post/fedibird_quote_uri.json
@@ -0,0 +1,54 @@
+{
+ "@context": [
+ "https://www.w3.org/ns/activitystreams",
+ {
+ "ostatus": "http://ostatus.org#",
+ "atomUri": "ostatus:atomUri",
+ "inReplyToAtomUri": "ostatus:inReplyToAtomUri",
+ "conversation": "ostatus:conversation",
+ "sensitive": "as:sensitive",
+ "toot": "http://joinmastodon.org/ns#",
+ "votersCount": "toot:votersCount",
+ "fedibird": "http://fedibird.com/ns#",
+ "quoteUri": "fedibird:quoteUri",
+ "expiry": "fedibird:expiry"
+ }
+ ],
+ "id": "https://fedibird.com/users/noellabo/statuses/107699335988346142",
+ "type": "Note",
+ "summary": null,
+ "inReplyTo": null,
+ "published": "2022-01-28T09:17:30Z",
+ "url": "https://fedibird.com/@noellabo/107699335988346142",
+ "attributedTo": "https://fedibird.com/users/noellabo",
+ "to": [
+ "https://www.w3.org/ns/activitystreams#Public"
+ ],
+ "cc": [
+ "https://fedibird.com/users/noellabo/followers"
+ ],
+ "sensitive": false,
+ "atomUri": "https://fedibird.com/users/noellabo/statuses/107699335988346142",
+ "inReplyToAtomUri": null,
+ "conversation": "tag:fedibird.com,2022-01-28:objectId=107699335988345290:objectType=Conversation",
+ "context": "https://fedibird.com/contexts/107699335988345290",
+ "quoteUri": "https://fedibird.com/users/yamako/statuses/107699333438289729",
+ "_misskey_quote": "https://fedibird.com/users/yamako/statuses/107699333438289729",
+ "_misskey_content": "美味しそう",
+ "content": "<p>美味しそう<span class=\"quote-inline\"><br/>QT: <a class=\"status-url-link\" data-status-account-acct=\"yamako\" data-status-id=\"107699333438289729\" href=\"https://fedibird.com/@yamako/107699333438289729\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">fedibird.com/@yamako/107699333</span><span class=\"invisible\">438289729</span></a></span></p>",
+ "contentMap": {
+ "ja": "<p>美味しそう<span class=\"quote-inline\"><br/>QT: <a class=\"status-url-link\" data-status-account-acct=\"yamako\" data-status-id=\"107699333438289729\" href=\"https://fedibird.com/@yamako/107699333438289729\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">fedibird.com/@yamako/107699333</span><span class=\"invisible\">438289729</span></a></span></p>"
+ },
+ "attachment": [],
+ "tag": [],
+ "replies": {
+ "id": "https://fedibird.com/users/noellabo/statuses/107699335988346142/replies",
+ "type": "Collection",
+ "first": {
+ "type": "CollectionPage",
+ "next": "https://fedibird.com/users/noellabo/statuses/107699335988346142/replies?only_other_accounts=true&page=true",
+ "partOf": "https://fedibird.com/users/noellabo/statuses/107699335988346142/replies",
+ "items": []
+ }
+ }
+}
diff --git a/test/fixtures/quote_post/fep-e232-tag-example.json b/test/fixtures/quote_post/fep-e232-tag-example.json
new file mode 100644
index 000000000..23c7fb5ac
--- /dev/null
+++ b/test/fixtures/quote_post/fep-e232-tag-example.json
@@ -0,0 +1,17 @@
+{
+ "@context": "https://www.w3.org/ns/activitystreams",
+ "type": "Note",
+ "content": "This is a quote:<br>RE: https://server.example/objects/123",
+ "tag": [
+ {
+ "type": "Link",
+ "mediaType": "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"",
+ "href": "https://server.example/objects/123",
+ "name": "RE: https://server.example/objects/123"
+ }
+ ],
+ "id": "https://server.example/objects/1",
+ "to": "https://server.example/users/1",
+ "attributedTo": "https://server.example/users/1",
+ "actor": "https://server.example/users/1"
+}
diff --git a/test/fixtures/quote_post/misskey_quote_post.json b/test/fixtures/quote_post/misskey_quote_post.json
new file mode 100644
index 000000000..59f677ca9
--- /dev/null
+++ b/test/fixtures/quote_post/misskey_quote_post.json
@@ -0,0 +1,46 @@
+{
+ "@context": [
+ "https://www.w3.org/ns/activitystreams",
+ "https://w3id.org/security/v1",
+ {
+ "manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
+ "sensitive": "as:sensitive",
+ "Hashtag": "as:Hashtag",
+ "quoteUrl": "as:quoteUrl",
+ "toot": "http://joinmastodon.org/ns#",
+ "Emoji": "toot:Emoji",
+ "featured": "toot:featured",
+ "discoverable": "toot:discoverable",
+ "schema": "http://schema.org#",
+ "PropertyValue": "schema:PropertyValue",
+ "value": "schema:value",
+ "misskey": "https://misskey.io/ns#",
+ "_misskey_content": "misskey:_misskey_content",
+ "_misskey_quote": "misskey:_misskey_quote",
+ "_misskey_reaction": "misskey:_misskey_reaction",
+ "_misskey_votes": "misskey:_misskey_votes",
+ "_misskey_talk": "misskey:_misskey_talk",
+ "isCat": "misskey:isCat",
+ "vcard": "http://www.w3.org/2006/vcard/ns#"
+ }
+ ],
+ "id": "https://misskey.io/notes/8vs6ylpfez",
+ "type": "Note",
+ "attributedTo": "https://misskey.io/users/7rkrarq81i",
+ "summary": null,
+ "content": "<p><span>投稿者の設定によるね<br>Fanboxについても投稿者によっては過去の投稿は高額なプランに移動してることがある<br><br>RE: </span><a href=\"https://misskey.io/notes/8vs6wxufd0\">https://misskey.io/notes/8vs6wxufd0</a></p>",
+ "_misskey_content": "投稿者の設定によるね\nFanboxについても投稿者によっては過去の投稿は高額なプランに移動してることがある",
+ "_misskey_quote": "https://misskey.io/notes/8vs6wxufd0",
+ "quoteUrl": "https://misskey.io/notes/8vs6wxufd0",
+ "published": "2022-01-21T16:38:30.243Z",
+ "to": [
+ "https://www.w3.org/ns/activitystreams#Public"
+ ],
+ "cc": [
+ "https://misskey.io/users/7rkrarq81i/followers"
+ ],
+ "inReplyTo": null,
+ "attachment": [],
+ "sensitive": false,
+ "tag": []
+}
diff --git a/test/fixtures/tesla_mock/aimu@misskey.io.json b/test/fixtures/tesla_mock/aimu@misskey.io.json
new file mode 100644
index 000000000..9ff4cb6d0
--- /dev/null
+++ b/test/fixtures/tesla_mock/aimu@misskey.io.json
@@ -0,0 +1,64 @@
+{
+ "@context": [
+ "https://www.w3.org/ns/activitystreams",
+ "https://w3id.org/security/v1",
+ {
+ "manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
+ "sensitive": "as:sensitive",
+ "Hashtag": "as:Hashtag",
+ "quoteUrl": "as:quoteUrl",
+ "toot": "http://joinmastodon.org/ns#",
+ "Emoji": "toot:Emoji",
+ "featured": "toot:featured",
+ "discoverable": "toot:discoverable",
+ "schema": "http://schema.org#",
+ "PropertyValue": "schema:PropertyValue",
+ "value": "schema:value",
+ "misskey": "https://misskey.io/ns#",
+ "_misskey_content": "misskey:_misskey_content",
+ "_misskey_quote": "misskey:_misskey_quote",
+ "_misskey_reaction": "misskey:_misskey_reaction",
+ "_misskey_votes": "misskey:_misskey_votes",
+ "_misskey_talk": "misskey:_misskey_talk",
+ "isCat": "misskey:isCat",
+ "vcard": "http://www.w3.org/2006/vcard/ns#"
+ }
+ ],
+ "type": "Person",
+ "id": "https://misskey.io/users/83ssedkv53",
+ "inbox": "https://misskey.io/users/83ssedkv53/inbox",
+ "outbox": "https://misskey.io/users/83ssedkv53/outbox",
+ "followers": "https://misskey.io/users/83ssedkv53/followers",
+ "following": "https://misskey.io/users/83ssedkv53/following",
+ "sharedInbox": "https://misskey.io/inbox",
+ "endpoints": {
+ "sharedInbox": "https://misskey.io/inbox"
+ },
+ "url": "https://misskey.io/@aimu",
+ "preferredUsername": "aimu",
+ "name": "あいむ",
+ "summary": "<p><span>わずかな作曲要素 巣穴で独り言<br>Twitter </span><a href=\"https://twitter.com/aimu_53\">https://twitter.com/aimu_53</a><span><br>Soundcloud </span><a href=\"https://soundcloud.com/aimu-53\">https://soundcloud.com/aimu-53</a></p>",
+ "icon": {
+ "type": "Image",
+ "url": "https://s3.arkjp.net/misskey/webpublic-3f7e93c0-34f5-443c-acc0-f415cb2342b4.jpg",
+ "sensitive": false,
+ "name": null
+ },
+ "image": {
+ "type": "Image",
+ "url": "https://s3.arkjp.net/misskey/webpublic-2db63d1d-490b-488b-ab62-c93c285f26b6.png",
+ "sensitive": false,
+ "name": null
+ },
+ "tag": [],
+ "manuallyApprovesFollowers": false,
+ "discoverable": true,
+ "publicKey": {
+ "id": "https://misskey.io/users/83ssedkv53#main-key",
+ "type": "Key",
+ "owner": "https://misskey.io/users/83ssedkv53",
+ "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1ylhePJ6qGHmwHSBP17b\nIosxGaiFKvgDBgZdm8vzvKeRSqJV9uLHfZL3pO/Zt02EwaZd2GohZAtBZEF8DbMA\n3s93WAesvyGF9mjGrYYKlhp/glwyrrrbf+RdD0DLtyDwRRlrxp3pS2lLmv5Tp1Zl\npH+UKpOnNrpQqjHI5P+lEc9bnflzbRrX+UiyLNsVAP80v4wt7SZfT/telrU6mDru\n998UdfhUo7bDKeDsHG1PfLpyhhtfdoZub4kBpkyacHiwAd+CdCjR54Eu7FDwVK3p\nY3JcrT2q5stgMqN1m4QgSL4XAADIotWwDYttTJejM1n9dr+6VWv5bs0F2Q/6gxOp\nu5DQZLk4Q+64U4LWNox6jCMOq3fYe0g7QalJIHnanYQQo+XjoH6S1Aw64gQ3Ip2Y\nZBmZREAOR7GMFVDPFnVnsbCHnIAv16TdgtLgQBAihkWEUuPqITLi8PMu6kMr3uyq\nYkObEfH0TNTcqaiVpoXv791GZLEUV5ROl0FSUANLNkHZZv29xZ5JDOBOR1rNBLyH\ngVtW8rpszYqOXwzX23hh4WsVXfB7YgNvIijwjiaWbzsecleaENGEnLNMiVKVumTj\nmtyTeFJpH0+OaSrUYpemRRJizmqIjklKsNwUEwUb2WcUUg92o56T2obrBkooabZe\nwgSXSKTOcjsR/ju7+AuIyvkCAwEAAQ==\n-----END PUBLIC KEY-----\n"
+ },
+ "isCat": true,
+ "vcard:bday": "5353-05-03"
+}
diff --git a/test/fixtures/tesla_mock/misskey.io_8vs6wxufd0.json b/test/fixtures/tesla_mock/misskey.io_8vs6wxufd0.json
new file mode 100644
index 000000000..323ca10ed
--- /dev/null
+++ b/test/fixtures/tesla_mock/misskey.io_8vs6wxufd0.json
@@ -0,0 +1,44 @@
+{
+ "@context": [
+ "https://www.w3.org/ns/activitystreams",
+ "https://w3id.org/security/v1",
+ {
+ "manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
+ "sensitive": "as:sensitive",
+ "Hashtag": "as:Hashtag",
+ "quoteUrl": "as:quoteUrl",
+ "toot": "http://joinmastodon.org/ns#",
+ "Emoji": "toot:Emoji",
+ "featured": "toot:featured",
+ "discoverable": "toot:discoverable",
+ "schema": "http://schema.org#",
+ "PropertyValue": "schema:PropertyValue",
+ "value": "schema:value",
+ "misskey": "https://misskey.io/ns#",
+ "_misskey_content": "misskey:_misskey_content",
+ "_misskey_quote": "misskey:_misskey_quote",
+ "_misskey_reaction": "misskey:_misskey_reaction",
+ "_misskey_votes": "misskey:_misskey_votes",
+ "_misskey_talk": "misskey:_misskey_talk",
+ "isCat": "misskey:isCat",
+ "vcard": "http://www.w3.org/2006/vcard/ns#"
+ }
+ ],
+ "id": "https://misskey.io/notes/8vs6wxufd0",
+ "type": "Note",
+ "attributedTo": "https://misskey.io/users/83ssedkv53",
+ "summary": null,
+ "content": "<p><span>Fantiaこれできないように過去のやつは従量課金だった気がする</span></p>",
+ "_misskey_content": "Fantiaこれできないように過去のやつは従量課金だった気がする",
+ "published": "2022-01-21T16:37:12.663Z",
+ "to": [
+ "https://www.w3.org/ns/activitystreams#Public"
+ ],
+ "cc": [
+ "https://misskey.io/users/83ssedkv53/followers"
+ ],
+ "inReplyTo": null,
+ "attachment": [],
+ "sensitive": false,
+ "tag": []
+}
diff --git a/test/pleroma/web/activity_pub/builder_test.exs b/test/pleroma/web/activity_pub/builder_test.exs
index eb175a1be..52058a0a3 100644
--- a/test/pleroma/web/activity_pub/builder_test.exs
+++ b/test/pleroma/web/activity_pub/builder_test.exs
@@ -44,5 +44,34 @@ defmodule Pleroma.Web.ActivityPub.BuilderTest do
assert {:ok, ^expected, []} = Builder.note(draft)
end
+
+ test "quote post" do
+ user = insert(:user)
+ note = insert(:note)
+
+ draft = %ActivityDraft{
+ user: user,
+ context: "2hu",
+ content_html: "<h1>This is :moominmamma: note</h1>",
+ quote_post: note,
+ extra: %{}
+ }
+
+ expected = %{
+ "actor" => user.ap_id,
+ "attachment" => [],
+ "content" => "<h1>This is :moominmamma: note</h1>",
+ "context" => "2hu",
+ "sensitive" => false,
+ "type" => "Note",
+ "quoteUrl" => note.data["id"],
+ "cc" => [],
+ "summary" => nil,
+ "tag" => [],
+ "to" => []
+ }
+
+ assert {:ok, ^expected, []} = Builder.note(draft)
+ end
end
end
diff --git a/test/pleroma/web/activity_pub/mrf/inline_quote_policy_test.exs b/test/pleroma/web/activity_pub/mrf/inline_quote_policy_test.exs
new file mode 100644
index 000000000..d5762766f
--- /dev/null
+++ b/test/pleroma/web/activity_pub/mrf/inline_quote_policy_test.exs
@@ -0,0 +1,112 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicyTest do
+ alias Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy
+ use Pleroma.DataCase
+
+ test "adds quote URL to post content" do
+ quote_url = "https://gleasonator.com/objects/1234"
+
+ activity = %{
+ "type" => "Create",
+ "actor" => "https://gleasonator.com/users/alex",
+ "object" => %{
+ "type" => "Note",
+ "content" => "Nice post",
+ "quoteUrl" => quote_url
+ }
+ }
+
+ {:ok, %{"object" => %{"content" => filtered}}} = InlineQuotePolicy.filter(activity)
+
+ assert filtered ==
+ "Nice post<span class=\"quote-inline\"><br/><br/><bdi>RT:</bdi> <a href=\"https://gleasonator.com/objects/1234\">https://gleasonator.com/objects/1234</a></span>"
+ end
+
+ test "adds quote URL to post content, custom template" do
+ clear_config([:mrf_inline_quote, :template], "{url}'s quoting")
+ quote_url = "https://gleasonator.com/objects/1234"
+
+ activity = %{
+ "type" => "Create",
+ "actor" => "https://gleasonator.com/users/alex",
+ "object" => %{
+ "type" => "Note",
+ "content" => "Nice post",
+ "quoteUrl" => quote_url
+ }
+ }
+
+ {:ok, %{"object" => %{"content" => filtered}}} = InlineQuotePolicy.filter(activity)
+
+ assert filtered ==
+ "Nice post<span class=\"quote-inline\"><br/><br/><a href=\"https://gleasonator.com/objects/1234\">https://gleasonator.com/objects/1234</a>'s quoting</span>"
+ end
+
+ test "doesn't add line breaks to markdown posts" do
+ quote_url = "https://gleasonator.com/objects/1234"
+
+ activity = %{
+ "type" => "Create",
+ "actor" => "https://gleasonator.com/users/alex",
+ "object" => %{
+ "type" => "Note",
+ "content" => "<p>Nice post</p>",
+ "quoteUrl" => quote_url
+ }
+ }
+
+ {:ok, %{"object" => %{"content" => filtered}}} = InlineQuotePolicy.filter(activity)
+
+ assert filtered ==
+ "<p>Nice post<span class=\"quote-inline\"><br/><br/><bdi>RT:</bdi> <a href=\"https://gleasonator.com/objects/1234\">https://gleasonator.com/objects/1234</a></span></p>"
+ end
+
+ test "ignores Misskey quote posts" do
+ object = File.read!("test/fixtures/quote_post/misskey_quote_post.json") |> Jason.decode!()
+
+ activity = %{
+ "type" => "Create",
+ "actor" => "https://misskey.io/users/7rkrarq81i",
+ "object" => object
+ }
+
+ {:ok, filtered} = InlineQuotePolicy.filter(activity)
+ assert filtered == activity
+ end
+
+ test "ignores Fedibird quote posts" do
+ object = File.read!("test/fixtures/quote_post/fedibird_quote_post.json") |> Jason.decode!()
+
+ # Normally the ObjectValidator will fix this before it reaches MRF
+ object = Map.put(object, "quoteUrl", object["quoteURL"])
+
+ activity = %{
+ "type" => "Create",
+ "actor" => "https://fedibird.com/users/noellabo",
+ "object" => object
+ }
+
+ {:ok, filtered} = InlineQuotePolicy.filter(activity)
+ assert filtered == activity
+ end
+
+ test "skips objects which already have an .inline-quote span" do
+ object =
+ File.read!("test/fixtures/quote_post/fedibird_quote_mismatched.json") |> Jason.decode!()
+
+ # Normally the ObjectValidator will fix this before it reaches MRF
+ object = Map.put(object, "quoteUrl", object["quoteUri"])
+
+ activity = %{
+ "type" => "Create",
+ "actor" => "https://fedibird.com/users/noellabo",
+ "object" => object
+ }
+
+ {:ok, filtered} = InlineQuotePolicy.filter(activity)
+ assert filtered == activity
+ end
+end
diff --git a/test/pleroma/web/activity_pub/mrf/quote_to_link_tag_policy_test.exs b/test/pleroma/web/activity_pub/mrf/quote_to_link_tag_policy_test.exs
new file mode 100644
index 000000000..96b49b6a0
--- /dev/null
+++ b/test/pleroma/web/activity_pub/mrf/quote_to_link_tag_policy_test.exs
@@ -0,0 +1,73 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.MRF.QuoteToLinkTagPolicyTest do
+ alias Pleroma.Web.ActivityPub.MRF.QuoteToLinkTagPolicy
+
+ use Pleroma.DataCase
+
+ require Pleroma.Constants
+
+ test "Add quote url to Link tag" do
+ quote_url = "https://gleasonator.com/objects/1234"
+
+ activity = %{
+ "type" => "Create",
+ "actor" => "https://gleasonator.com/users/alex",
+ "object" => %{
+ "type" => "Note",
+ "content" => "Nice post",
+ "quoteUrl" => quote_url
+ }
+ }
+
+ {:ok, %{"object" => object}} = QuoteToLinkTagPolicy.filter(activity)
+
+ assert object["tag"] == [
+ %{
+ "type" => "Link",
+ "href" => quote_url,
+ "mediaType" => Pleroma.Constants.activity_json_canonical_mime_type()
+ }
+ ]
+ end
+
+ test "Add quote url to Link tag, append to the end" do
+ quote_url = "https://gleasonator.com/objects/1234"
+
+ activity = %{
+ "type" => "Create",
+ "actor" => "https://gleasonator.com/users/alex",
+ "object" => %{
+ "type" => "Note",
+ "content" => "Nice post",
+ "quoteUrl" => quote_url,
+ "tag" => [%{"type" => "Hashtag", "name" => "#foo"}]
+ }
+ }
+
+ {:ok, %{"object" => object}} = QuoteToLinkTagPolicy.filter(activity)
+
+ assert [_, tag] = object["tag"]
+
+ assert tag == %{
+ "type" => "Link",
+ "href" => quote_url,
+ "mediaType" => Pleroma.Constants.activity_json_canonical_mime_type()
+ }
+ end
+
+ test "Bypass posts without quoteUrl" do
+ activity = %{
+ "type" => "Create",
+ "actor" => "https://gleasonator.com/users/alex",
+ "object" => %{
+ "type" => "Note",
+ "content" => "Nice post"
+ }
+ }
+
+ assert {:ok, ^activity} = QuoteToLinkTagPolicy.filter(activity)
+ end
+end
diff --git a/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs b/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs
index c7a62be18..4703c3801 100644
--- a/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs
+++ b/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs
@@ -116,4 +116,53 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidatorTest
%{valid?: true} = ArticleNotePageValidator.cast_and_validate(note)
end
+
+ test "Fedibird quote post" do
+ insert(:user, ap_id: "https://fedibird.com/users/noellabo")
+
+ data = File.read!("test/fixtures/quote_post/fedibird_quote_post.json") |> Jason.decode!()
+ cng = ArticleNotePageValidator.cast_and_validate(data)
+
+ assert cng.valid?
+ assert cng.changes.quoteUrl == "https://misskey.io/notes/8vsn2izjwh"
+ end
+
+ test "Fedibird quote post with quoteUri field" do
+ insert(:user, ap_id: "https://fedibird.com/users/noellabo")
+
+ data = File.read!("test/fixtures/quote_post/fedibird_quote_uri.json") |> Jason.decode!()
+ cng = ArticleNotePageValidator.cast_and_validate(data)
+
+ assert cng.valid?
+ assert cng.changes.quoteUrl == "https://fedibird.com/users/yamako/statuses/107699333438289729"
+ end
+
+ test "Misskey quote post" do
+ insert(:user, ap_id: "https://misskey.io/users/7rkrarq81i")
+
+ data = File.read!("test/fixtures/quote_post/misskey_quote_post.json") |> Jason.decode!()
+ cng = ArticleNotePageValidator.cast_and_validate(data)
+
+ assert cng.valid?
+ assert cng.changes.quoteUrl == "https://misskey.io/notes/8vs6wxufd0"
+ end
+
+ test "Parse tag as quote" do
+ # https://codeberg.org/fediverse/fep/src/branch/main/fep/e232/fep-e232.md
+
+ insert(:user, ap_id: "https://server.example/users/1")
+
+ data = File.read!("test/fixtures/quote_post/fep-e232-tag-example.json") |> Jason.decode!()
+ cng = ArticleNotePageValidator.cast_and_validate(data)
+
+ assert cng.valid?
+ assert cng.changes.quoteUrl == "https://server.example/objects/123"
+
+ assert Enum.at(cng.changes.tag, 0).changes == %{
+ type: "Link",
+ mediaType: "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"",
+ href: "https://server.example/objects/123",
+ name: "RE: https://server.example/objects/123"
+ }
+ end
end
diff --git a/test/pleroma/web/activity_pub/transmogrifier_test.exs b/test/pleroma/web/activity_pub/transmogrifier_test.exs
index 3e0c8dc65..5e58d75db 100644
--- a/test/pleroma/web/activity_pub/transmogrifier_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier_test.exs
@@ -123,7 +123,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert activity.data["context"] == object.data["context"]
end
- test "it drops link tags" do
+ test "it keeps link tags" do
insert(:user, ap_id: "https://example.org/users/alice")
message = File.read!("test/fixtures/fep-e232.json") |> Jason.decode!()
@@ -131,10 +131,29 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert {:ok, activity} = Transmogrifier.handle_incoming(message)
object = Object.normalize(activity)
- assert length(object.data["tag"]) == 1
+ assert [%{"type" => "Mention"}, %{"type" => "Link"}] = object.data["tag"]
+ end
+
+ test "it accepts quote posts" do
+ insert(:user, ap_id: "https://misskey.io/users/7rkrarq81i")
+
+ object = File.read!("test/fixtures/quote_post/misskey_quote_post.json") |> Jason.decode!()
+
+ message = %{
+ "@context" => "https://www.w3.org/ns/activitystreams",
+ "type" => "Create",
+ "actor" => "https://misskey.io/users/7rkrarq81i",
+ "object" => object
+ }
+
+ assert {:ok, activity} = Transmogrifier.handle_incoming(message)
- tag = object.data["tag"] |> List.first()
- assert tag["type"] == "Mention"
+ # Object was created in the database
+ object = Object.normalize(activity)
+ assert object.data["quoteUrl"] == "https://misskey.io/notes/8vs6wxufd0"
+
+ # It fetched the quoted post
+ assert Object.normalize("https://misskey.io/notes/8vs6wxufd0")
end
end
@@ -350,6 +369,20 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
}
} = prepared["object"]
end
+
+ test "it prepares a quote post" do
+ user = insert(:user)
+
+ {:ok, quoted_post} = CommonAPI.post(user, %{status: "hey"})
+ {:ok, quote_post} = CommonAPI.post(user, %{status: "hey", quote_id: quoted_post.id})
+
+ {:ok, modified} = Transmogrifier.prepare_outgoing(quote_post.data)
+
+ %{data: %{"id" => quote_id}} = Object.normalize(quoted_post)
+
+ assert modified["object"]["quoteUrl"] == quote_id
+ assert modified["object"]["quoteUri"] == quote_id
+ end
end
describe "actor rewriting" do
diff --git a/test/pleroma/web/common_api/activity_draft_test.exs b/test/pleroma/web/common_api/activity_draft_test.exs
new file mode 100644
index 000000000..02bc6cf3b
--- /dev/null
+++ b/test/pleroma/web/common_api/activity_draft_test.exs
@@ -0,0 +1,33 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.CommonAPI.ActivityDraftTest do
+ use Pleroma.DataCase
+
+ alias Pleroma.Web.CommonAPI
+ alias Pleroma.Web.CommonAPI.ActivityDraft
+
+ import Pleroma.Factory
+
+ test "create/2 with a quote post" do
+ user = insert(:user)
+ another_user = insert(:user)
+
+ {:ok, direct} = CommonAPI.post(user, %{status: ".", visibility: "direct"})
+ {:ok, private} = CommonAPI.post(user, %{status: ".", visibility: "private"})
+ {:ok, unlisted} = CommonAPI.post(user, %{status: ".", visibility: "unlisted"})
+ {:ok, local} = CommonAPI.post(user, %{status: ".", visibility: "local"})
+ {:ok, public} = CommonAPI.post(user, %{status: ".", visibility: "public"})
+
+ {:error, _} = ActivityDraft.create(user, %{status: "nice", quote_id: direct.id})
+ {:ok, _} = ActivityDraft.create(user, %{status: "nice", quote_id: private.id})
+ {:error, _} = ActivityDraft.create(another_user, %{status: "nice", quote_id: private.id})
+ {:ok, _} = ActivityDraft.create(user, %{status: "nice", quote_id: unlisted.id})
+ {:ok, _} = ActivityDraft.create(another_user, %{status: "nice", quote_id: unlisted.id})
+ {:ok, _} = ActivityDraft.create(user, %{status: "nice", quote_id: local.id})
+ {:ok, _} = ActivityDraft.create(another_user, %{status: "nice", quote_id: local.id})
+ {:ok, _} = ActivityDraft.create(user, %{status: "nice", quote_id: public.id})
+ {:ok, _} = ActivityDraft.create(another_user, %{status: "nice", quote_id: public.id})
+ end
+end
diff --git a/test/pleroma/web/common_api_test.exs b/test/pleroma/web/common_api_test.exs
index 0d76d6581..a98b16d4b 100644
--- a/test/pleroma/web/common_api_test.exs
+++ b/test/pleroma/web/common_api_test.exs
@@ -796,6 +796,53 @@ defmodule Pleroma.Web.CommonAPITest do
scheduled_at: expires_at
)
end
+
+ test "it allows quote posting" do
+ user = insert(:user)
+
+ {:ok, quoted} = CommonAPI.post(user, %{status: "Hello world"})
+ {:ok, quote_post} = CommonAPI.post(user, %{status: "nice post", quote_id: quoted.id})
+
+ quoted = Object.normalize(quoted)
+ quote_post = Object.normalize(quote_post)
+
+ assert quote_post.data["quoteUrl"] == quoted.data["id"]
+
+ # The OP is not mentioned
+ refute quoted.data["actor"] in quote_post.data["to"]
+ end
+
+ test "quote posting with explicit addressing doesn't mention the OP" do
+ user = insert(:user)
+
+ {:ok, quoted} = CommonAPI.post(user, %{status: "Hello world"})
+
+ {:ok, quote_post} =
+ CommonAPI.post(user, %{status: "nice post", quote_id: quoted.id, to: []})
+
+ assert Object.normalize(quote_post).data["to"] == [Pleroma.Constants.as_public()]
+ end
+
+ test "quote posting visibility" do
+ user = insert(:user)
+ another_user = insert(:user)
+
+ {:ok, direct} = CommonAPI.post(user, %{status: ".", visibility: "direct"})
+ {:ok, private} = CommonAPI.post(user, %{status: ".", visibility: "private"})
+ {:ok, unlisted} = CommonAPI.post(user, %{status: ".", visibility: "unlisted"})
+ {:ok, local} = CommonAPI.post(user, %{status: ".", visibility: "local"})
+ {:ok, public} = CommonAPI.post(user, %{status: ".", visibility: "public"})
+
+ {:error, _} = CommonAPI.post(user, %{status: "nice", quote_id: direct.id})
+ {:ok, _} = CommonAPI.post(user, %{status: "nice", quote_id: private.id})
+ {:error, _} = CommonAPI.post(another_user, %{status: "nice", quote_id: private.id})
+ {:ok, _} = CommonAPI.post(user, %{status: "nice", quote_id: unlisted.id})
+ {:ok, _} = CommonAPI.post(another_user, %{status: "nice", quote_id: unlisted.id})
+ {:ok, _} = CommonAPI.post(user, %{status: "nice", quote_id: local.id})
+ {:ok, _} = CommonAPI.post(another_user, %{status: "nice", quote_id: local.id})
+ {:ok, _} = CommonAPI.post(user, %{status: "nice", quote_id: public.id})
+ {:ok, _} = CommonAPI.post(another_user, %{status: "nice", quote_id: public.id})
+ end
end
describe "reactions" do
diff --git a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
index 76c289ee7..de3b52e26 100644
--- a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
@@ -125,6 +125,28 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
)
end
+ test "posting a quote post", %{conn: conn} do
+ user = insert(:user)
+
+ {:ok, %{id: activity_id} = activity} = CommonAPI.post(user, %{status: "yolo"})
+ %{data: %{"id" => quote_url}} = Object.normalize(activity)
+
+ conn =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/statuses", %{
+ "status" => "indeed",
+ "quote_id" => activity_id
+ })
+
+ assert %{
+ "id" => id,
+ "pleroma" => %{"quote" => %{"id" => ^activity_id}, "quote_url" => ^quote_url}
+ } = json_response_and_validate_schema(conn, 200)
+
+ assert Activity.get_by_id(id)
+ end
+
test "it fails to create a status if `expires_in` is less or equal than an hour", %{
conn: conn
} do
diff --git a/test/pleroma/web/mastodon_api/views/status_view_test.exs b/test/pleroma/web/mastodon_api/views/status_view_test.exs
index b93335190..baa9b32f5 100644
--- a/test/pleroma/web/mastodon_api/views/status_view_test.exs
+++ b/test/pleroma/web/mastodon_api/views/status_view_test.exs
@@ -326,6 +326,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
conversation_id: convo_id,
context: object_data["context"],
in_reply_to_account_acct: nil,
+ quote: nil,
+ quote_id: nil,
+ quote_url: nil,
+ quote_visible: false,
content: %{"text/plain" => HTML.strip_tags(object_data["content"])},
spoiler_text: %{"text/plain" => HTML.strip_tags(object_data["summary"])},
expires_at: nil,
@@ -422,6 +426,88 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
assert status.in_reply_to_id == to_string(note.id)
end
+ test "a quote post" do
+ post = insert(:note_activity)
+ user = insert(:user)
+
+ {:ok, quote_post} = CommonAPI.post(user, %{status: "he", quote_id: post.id})
+ {:ok, quoted_quote_post} = CommonAPI.post(user, %{status: "yo", quote_id: quote_post.id})
+
+ status = StatusView.render("show.json", %{activity: quoted_quote_post})
+
+ assert status.pleroma.quote.id == to_string(quote_post.id)
+ assert status.pleroma.quote_id == to_string(quote_post.id)
+ assert status.pleroma.quote_url == Object.normalize(quote_post).data["id"]
+ assert status.pleroma.quote_visible
+
+ # Quotes don't go more than one level deep
+ refute status.pleroma.quote.pleroma.quote
+ assert status.pleroma.quote.pleroma.quote_id == to_string(post.id)
+ assert status.pleroma.quote.pleroma.quote_url == Object.normalize(post).data["id"]
+ assert status.pleroma.quote.pleroma.quote_visible
+
+ # In an index
+ [status] = StatusView.render("index.json", %{activities: [quoted_quote_post], as: :activity})
+
+ assert status.pleroma.quote.id == to_string(quote_post.id)
+ end
+
+ test "quoted private post" do
+ user = insert(:user)
+
+ # Insert a private post
+ private = insert(:followers_only_note_activity, user: user)
+ private_object = Object.normalize(private)
+
+ # Create a public post quoting the private post
+ quote_private =
+ insert(:note_activity, note: insert(:note, data: %{"quoteUrl" => private_object.data["id"]}))
+
+ status = StatusView.render("show.json", %{activity: quote_private})
+
+ # The quote isn't rendered
+ refute status.pleroma.quote
+ assert status.pleroma.quote_url == private_object.data["id"]
+ refute status.pleroma.quote_visible
+
+ # After following the user, the quote is rendered
+ follower = insert(:user)
+ CommonAPI.follow(follower, user)
+
+ status = StatusView.render("show.json", %{activity: quote_private, for: follower})
+ assert status.pleroma.quote.id == to_string(private.id)
+ assert status.pleroma.quote_visible
+ end
+
+ test "quoted direct message" do
+ # Insert a direct message
+ direct = insert(:direct_note_activity)
+ direct_object = Object.normalize(direct)
+
+ # Create a public post quoting the direct message
+ quote_direct =
+ insert(:note_activity, note: insert(:note, data: %{"quoteUrl" => direct_object.data["id"]}))
+
+ status = StatusView.render("show.json", %{activity: quote_direct})
+
+ # The quote isn't rendered
+ refute status.pleroma.quote
+ assert status.pleroma.quote_url == direct_object.data["id"]
+ refute status.pleroma.quote_visible
+ end
+
+ test "repost of quote post" do
+ post = insert(:note_activity)
+ user = insert(:user)
+
+ {:ok, quote_post} = CommonAPI.post(user, %{status: "he", quote_id: post.id})
+ {:ok, repost} = CommonAPI.repeat(quote_post.id, user)
+
+ [status] = StatusView.render("index.json", %{activities: [repost], as: :activity})
+
+ assert status.reblog.pleroma.quote.id == to_string(post.id)
+ end
+
test "contains mentions" do
user = insert(:user)
mentioned = insert(:user)
diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex
index b0cf613ac..78a367024 100644
--- a/test/support/http_request_mock.ex
+++ b/test/support/http_request_mock.ex
@@ -1380,6 +1380,15 @@ defmodule HttpRequestMock do
}}
end
+ def get("https://misskey.io/users/83ssedkv53", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/aimu@misskey.io.json"),
+ headers: activitypub_object_headers()
+ }}
+ end
+
def get("https://gleasonator.com/users/macgirvin", _, _, _) do
{:ok,
%Tesla.Env{
@@ -1446,6 +1455,15 @@ defmodule HttpRequestMock do
}}
end
+ def get("https://misskey.io/notes/8vs6wxufd0", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/misskey.io_8vs6wxufd0.json"),
+ headers: activitypub_object_headers()
+ }}
+ end
+
def get(url, query, body, headers) do
{:error,
"Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{inspect(headers)}"}