summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/fixtures/custom-emoji-reaction.json28
-rw-r--r--test/fixtures/fep-e232.json31
-rw-r--r--test/fixtures/hubzilla-actor.json1
-rw-r--r--test/fixtures/hubzilla-create-image.json1
-rw-r--r--test/fixtures/mastodon-nodeinfo20.json1
-rw-r--r--test/fixtures/mastodon-well-known-nodeinfo.json1
-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/fixtures/wildebeest-nodeinfo21.json1
-rw-r--r--test/fixtures/wildebeest-well-known-nodeinfo.json1
-rw-r--r--test/fixtures/xml_billion_laughs.xml15
-rw-r--r--test/mix/tasks/pleroma/openapi_spec_test.exs62
-rw-r--r--test/pleroma/bbs/handler_test.exs89
-rw-r--r--test/pleroma/config/release_runtime_provider_test.exs2
-rw-r--r--test/pleroma/ecto_type/activity_pub/object_validators/bare_uri_test.ex25
-rw-r--r--test/pleroma/instances/instance_test.exs60
-rw-r--r--test/pleroma/integration/mastodon_websocket_test.exs352
-rw-r--r--test/pleroma/notification_test.exs4
-rw-r--r--test/pleroma/object_test.exs38
-rw-r--r--test/pleroma/upload/filter/only_media_test.exs32
-rw-r--r--test/pleroma/user/backup_test.exs98
-rw-r--r--test/pleroma/user/import_test.exs1
-rw-r--r--test/pleroma/user_search_test.exs1
-rw-r--r--test/pleroma/user_test.exs11
-rw-r--r--test/pleroma/web/activity_pub/activity_pub_controller_test.exs1
-rw-r--r--test/pleroma/web/activity_pub/activity_pub_test.exs9
-rw-r--r--test/pleroma/web/activity_pub/builder_test.exs29
-rw-r--r--test/pleroma/web/activity_pub/mrf/emoji_policy_test.exs425
-rw-r--r--test/pleroma/web/activity_pub/mrf/force_mentions_in_content_test.exs51
-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/mrf/utils_test.exs19
-rw-r--r--test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs49
-rw-r--r--test/pleroma/web/activity_pub/object_validators/emoji_react_handling_test.exs60
-rw-r--r--test/pleroma/web/activity_pub/publisher_test.exs15
-rw-r--r--test/pleroma/web/activity_pub/side_effects_test.exs2
-rw-r--r--test/pleroma/web/activity_pub/transmogrifier/emoji_react_handling_test.exs53
-rw-r--r--test/pleroma/web/activity_pub/transmogrifier/image_handling_test.exs50
-rw-r--r--test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs2
-rw-r--r--test/pleroma/web/activity_pub/transmogrifier_test.exs99
-rw-r--r--test/pleroma/web/activity_pub/utils_test.exs27
-rw-r--r--test/pleroma/web/admin_api/controllers/config_controller_test.exs9
-rw-r--r--test/pleroma/web/admin_api/controllers/frontend_controller_test.exs1
-rw-r--r--test/pleroma/web/admin_api/controllers/report_controller_test.exs21
-rw-r--r--test/pleroma/web/api_spec/scopes/compiler_test.exs56
-rw-r--r--test/pleroma/web/common_api/activity_draft_test.exs33
-rw-r--r--test/pleroma/web/common_api/utils_test.exs17
-rw-r--r--test/pleroma/web/common_api_test.exs86
-rw-r--r--test/pleroma/web/federator_test.exs6
-rw-r--r--test/pleroma/web/mastodon_api/controllers/account_controller_test.exs33
-rw-r--r--test/pleroma/web/mastodon_api/controllers/status_controller_test.exs343
-rw-r--r--test/pleroma/web/mastodon_api/update_credentials_test.exs52
-rw-r--r--test/pleroma/web/mastodon_api/views/notification_view_test.exs42
-rw-r--r--test/pleroma/web/mastodon_api/views/status_view_test.exs149
-rw-r--r--test/pleroma/web/metadata/providers/rel_me_test.exs17
-rw-r--r--test/pleroma/web/metadata/providers/twitter_card_test.exs3
-rw-r--r--test/pleroma/web/pleroma_api/controllers/emoji_reaction_controller_test.exs191
-rw-r--r--test/pleroma/web/pleroma_api/views/backup_view_test.exs39
-rw-r--r--test/pleroma/web/plugs/uploaded_media_plug_test.exs4
-rw-r--r--test/pleroma/web/streamer_test.exs72
-rw-r--r--test/pleroma/web/xml_test.exs5
-rw-r--r--test/support/factory.ex1
-rw-r--r--test/support/http_request_mock.ex18
-rw-r--r--test/test_helper.exs2
69 files changed, 3197 insertions, 265 deletions
diff --git a/test/fixtures/custom-emoji-reaction.json b/test/fixtures/custom-emoji-reaction.json
new file mode 100644
index 000000000..003de0511
--- /dev/null
+++ b/test/fixtures/custom-emoji-reaction.json
@@ -0,0 +1,28 @@
+{
+ "@context": [
+ "https://www.w3.org/ns/activitystreams",
+ "https://w3id.org/security/v1",
+ {
+ "Hashtag": "as:Hashtag"
+ }
+ ],
+ "type": "Like",
+ "id": "https://misskey.local.live/likes/917ocsybgp",
+ "actor": "https://misskey.local.live/users/8x8yep20u2",
+ "object": "https://pleroma.local.live/objects/89937a53-2692-4631-bb62-770091267391",
+ "content": ":hanapog:",
+ "_misskey_reaction": ":hanapog:",
+ "tag": [
+ {
+ "id": "https://misskey.local.live/emojis/hanapog",
+ "type": "Emoji",
+ "name": ":hanapog:",
+ "updated": "2022-06-07T12:00:05.773Z",
+ "icon": {
+ "type": "Image",
+ "mediaType": "image/png",
+ "url": "https://misskey.local.live/files/webpublic-8f8a9768-7264-4171-88d6-2356aabeadcd"
+ }
+ }
+ ]
+}
diff --git a/test/fixtures/fep-e232.json b/test/fixtures/fep-e232.json
new file mode 100644
index 000000000..e9d12ae35
--- /dev/null
+++ b/test/fixtures/fep-e232.json
@@ -0,0 +1,31 @@
+{
+ "@context": "https://www.w3.org/ns/activitystreams",
+ "type": "Create",
+ "actor": "https://example.org/users/alice",
+ "object": {
+ "id": "https://example.org/objects/10",
+ "type": "Note",
+ "attributedTo": "https://example.org/users/alice",
+ "content": "<p>test <a href=\"https://example.org/objects/9\">https://example.org/objects/9</a></p>",
+ "published": "2022-10-01T21:30:05.211215Z",
+ "tag": [
+ {
+ "name": "@bob@example.net",
+ "type": "Mention",
+ "href": "https://example.net/users/bob"
+ },
+ {
+ "name": "https://example.org/objects/9",
+ "type": "Link",
+ "href": "https://example.org/objects/9",
+ "mediaType": "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
+ }
+ ],
+ "to": [
+ "https://www.w3.org/ns/activitystreams#Public"
+ ],
+ "cc": [
+ "https://example.org/users/alice/followers"
+ ]
+ }
+}
diff --git a/test/fixtures/hubzilla-actor.json b/test/fixtures/hubzilla-actor.json
new file mode 100644
index 000000000..445d6413c
--- /dev/null
+++ b/test/fixtures/hubzilla-actor.json
@@ -0,0 +1 @@
+{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1","https://hub.somaton.com/apschema/v1.9"],"type":"Person","id":"https://hub.somaton.com/channel/testc6","preferredUsername":"testc6","name":"testc6 lala","updated":"2021-08-29T10:07:23Z","icon":{"type":"Image","mediaType":"image/png","updated":"2021-10-09T04:54:35Z","url":"https://hub.somaton.com/photo/profile/l/33","height":300,"width":300},"url":"https://hub.somaton.com/channel/testc6","publicKey":{"id":"https://hub.somaton.com/channel/testc6","owner":"https://hub.somaton.com/channel/testc6","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq5ep+6MhhaAiqZSd8nXe\nUAokXNgqTr/DjUic5VDudjQgvetchaiBUieBnqpJSPNNAvvf6Qs4eDW4w2JQeA6y\nqEplKrmb8l1EyhwXeFLDUGQdf0f6hg++x5mIrO6uX0tlQGU6nutvhItn6JMZc5GU\nv3C/UW0OfHCCdHSGZ/1nIqq1P98FqF0+PA1pvTHCkLr4kcKzfpmkLjsccUSq0FGh\nQF+paW9FU89o4hkaH/X3E/Ac7DL8zgcyt29KSj4eUIvjBIEPAMdRno345fiZ+QYr\nlYQYaBC2gvozjxtxl9MyfqjBRzfl9VDHzoDvMn5+LD5dCRB1zOESv/b3EpiHYqXl\nwiPzP9az8e8cw6D72n/Mlrf27yIuVAdwaGdbAwekjIQZHIDoP0XNnA5i31RLpEMI\nbNpH47ChtjxeilQZ3va6qIShYfGlndpy/rx4i4Yt4xIG+BbGb/dWo3AbtHi64fPZ\nMoLuR71sEBe7uAvalJ+lopxuQ2qLJpCInukQ13p/G/n9tVDwbfGyumzr5hHk7JoY\nN+JqH737MCZqb9dRDof+fju58GY1VzFjBph38sHYJh0ykA+2BzYU2+nT7CDXfKWA\nsmHhizp7haoPjl/yclZG5FJwg3oqHTD14dASUs+OI4K+Q//74wfb4/6E3CDyOkW3\nUj+8TPZooKulxtQ9ezergr0CAwEAAQ==\n-----END PUBLIC KEY-----\n"},"outbox":"https://hub.somaton.com/outbox/testc6","inbox":"https://hub.somaton.com/inbox/testc6","followers":"https://hub.somaton.com/followers/testc6","following":"https://hub.somaton.com/following/testc6","endpoints":{"sharedInbox":"https://hub.somaton.com/inbox"},"discoverable":false,"signature":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1"],"type":"RsaSignature2017","nonce":"8d6dea03f04cbb7faaf43958a4cf39a115ff1c61c7febaa6154c463eab9a42c8","creator":"https://hub.somaton.com/channel/testc6","created":"2021-10-13T18:21:48Z","signatureValue":"N4CJBO2K/8v7KI97REyJXaSYOlLWscuEDlODDnjNYD1fbVQFO3s2JtqPcN2lVJvNTlW5HUze+owaAYNcvZe3mNm1iz05Xru3s8yRA8bNCdKBuWd/3zb3/JQVkbSb09D2PloeuoKBQmPIn+dNiTyFR0jxLsxCXXTomGKigWPtTOUIt52Dv9MFJ3jRZmfoykT9bHrAIVCASHoiluhTkPAzc6pt0lSyZd0D3X4J1K4/sLXa8HRoooMFu2dHWfqV4tyLU9WzofAhvnYg9tEbKCH42DIAbwDfjAeC4qL8xkqAlYWLvXYVGH76cZLdp9Zuv1p3NHqaPEJ85MbuaUkfnU75Bx/Fcfoi0pEieWRdFvMx5b/UFwGbJd6iSAO1zRbGYTPEMPWHzh0AEAaLeyY+g3ZmpNu88ujrIr8iJ1U4EkjOBn8ooxA5LaI2fXDiYC2NwRiAbY+xVtgJgvHDi9tXCdvzjZWfU/cgiwF/cYMbsB2BCyPRd+XZhudfXSOysFC4WYnawhiRVevba9lQ6rEP4FMepOGq4ZOSGzxgw2xNIXpu0IkrxX5mEv/ahEhDy1KGRIFc0GnPJrv3kMVxJrZ7SF8PNAGqftQBLkqQR+SEygs3XB4cd2DQ2lPeiMd8+Xv+lBjtzZtZAM/Y4CZCOdV9DHXDGNSKKFDzzna4QcUzQ+KRc8w="}} \ No newline at end of file
diff --git a/test/fixtures/hubzilla-create-image.json b/test/fixtures/hubzilla-create-image.json
new file mode 100644
index 000000000..9f0669bb7
--- /dev/null
+++ b/test/fixtures/hubzilla-create-image.json
@@ -0,0 +1 @@
+{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1","https://hub.somaton.com/apschema/v1.9"],"type":"Create","id":"https://hub.somaton.com/activity/452583b2-7e1f-4ac3-8334-ff666f134afe","diaspora:guid":"452583b2-7e1f-4ac3-8334-ff666f134afe","name":"daf82c18ef92a84cda72(1).jpg","published":"2021-10-12T21:28:26Z","actor":"https://hub.somaton.com/channel/testc6","object":{"type":"Image","name":"daf82c18ef92a84cda72(1).jpg","published":"2021-10-12T21:28:23Z","updated":"2021-10-12T21:28:23Z","attributedTo":"https://hub.somaton.com/channel/testc6","id":"https://hub.somaton.com/photo/452583b2-7e1f-4ac3-8334-ff666f134afe","url":[{"type":"Link","mediaType":"image/jpeg","href":"https://hub.somaton.com/photo/452583b2-7e1f-4ac3-8334-ff666f134afe-0.jpg","width":2200,"height":2200},{"type":"Link","mediaType":"image/jpeg","href":"https://hub.somaton.com/photo/452583b2-7e1f-4ac3-8334-ff666f134afe-1.jpg","width":1024,"height":1024},{"type":"Link","mediaType":"image/jpeg","href":"https://hub.somaton.com/photo/452583b2-7e1f-4ac3-8334-ff666f134afe-2.jpg","width":640,"height":640},{"type":"Link","mediaType":"image/jpeg","href":"https://hub.somaton.com/photo/452583b2-7e1f-4ac3-8334-ff666f134afe-3.jpg","width":320,"height":320},{"type":"Link","mediaType":"text/html","href":"https://hub.somaton.com/photos/testc6/image/452583b2-7e1f-4ac3-8334-ff666f134afe"}],"source":{"content":"[footer][zrl=https://hub.somaton.com/channel/testc6]testc6 lala[/zrl] posted [zrl=https://hub.somaton.com/photos/testc6/image/452583b2-7e1f-4ac3-8334-ff666f134afe]a new photo[/zrl] to [zrl=https://hub.somaton.com/photos/testc6/album/1e9b0d74-633e-4bd0-b37f-694bb0ed0145]test[/zrl][/footer]","mediaType":"text/bbcode"},"content":"<div class=\"wall-item-footer\"><a class=\"zrl\" href=\"https://hub.somaton.com/channel/testc6\" target=\"_blank\" rel=\"nofollow noopener\" >testc6 lala</a> posted <a class=\"zrl\" href=\"https://hub.somaton.com/photos/testc6/image/452583b2-7e1f-4ac3-8334-ff666f134afe\" target=\"_blank\" rel=\"nofollow noopener\" >a new photo</a> to <a class=\"zrl\" href=\"https://hub.somaton.com/photos/testc6/album/1e9b0d74-633e-4bd0-b37f-694bb0ed0145\" target=\"_blank\" rel=\"nofollow noopener\" >test</a></div>","to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://hub.somaton.com/followers/testc6"]},"target":{"type":"orderedCollection","name":"test","id":"https://hub.somaton.com/album/testc6/test"},"to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://hub.somaton.com/followers/testc6"],"signature":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1"],"type":"RsaSignature2017","nonce":"e0d077edccf262f02ed59ff67e91a5324ccaffc3d2b3f23793b4bd24cdbe70bb","creator":"https://hub.somaton.com/channel/testc6","created":"2021-10-13T18:39:05Z","signatureValue":"YYU0/17PqqUmLCn4oVS2N62rV1G9WQ+wLax2cI+EpMw/WOWKuVvtGrvhzciQ5ITXoh3scrZRYH8Bke1jDWkjL9YtjVD6TjMsv6f3OoO1vvMNgEfQfgZJ78QQt5MoLrT2mkRa35lSmVHkTDROKJPrwIAnpN6bDb577wZ63BsuBjqW7ca/E6oXSIr+meCXv3kqkyYDSz0ImYvVmki+OfX97xbYkQlzM06EgK1LZTHfuf4sk09hVfDDqVB9tHO4ObYQCYNiOWRHjA5S1Cw8WX1OQJ+GCQ8yxHmtiU3tJsxeYhxGs7VEmTLUvf/QZ0VTPumkd1CewdxzNGvAP3f9JCakuV7eyk88oqF+p7xxfxmBjLYbMTuhrcZIdUdMcjW9pENOYBbt+a+FhPsjbm8zVU3iKPqe/8UAvo01hGW7jiKJUm4qdcX3H3MExTLEFuz0NTeqxl4djlyGTT9KBqNouD+/oSSgwm6qeRZ5y3RsC27N0HRbg74qNXhhWQZVWQtHdSCHjAfHVPOSpjxpSPs7qkMLQ0vPsVsCsukZz8JCoXRo+JoKuaiaRgfiIRGNBO/XEicKMyu2JCU+UmkroiDJHy+4IfZRevnlneRa1jmu5KA/4xk5KU8l0I0Inap7TSPhv14Ex2sF89LkT8MbcDM3S3QL4urYsQj37zOKRDTFzE96TmI="}} \ No newline at end of file
diff --git a/test/fixtures/mastodon-nodeinfo20.json b/test/fixtures/mastodon-nodeinfo20.json
new file mode 100644
index 000000000..35010fdf0
--- /dev/null
+++ b/test/fixtures/mastodon-nodeinfo20.json
@@ -0,0 +1 @@
+{"version":"2.0","software":{"name":"mastodon","version":"4.1.0"},"protocols":["activitypub"],"services":{"outbound":[],"inbound":[]},"usage":{"users":{"total":971090,"activeMonth":167218,"activeHalfyear":384808},"localPosts":52071541},"openRegistrations":true,"metadata":{}} \ No newline at end of file
diff --git a/test/fixtures/mastodon-well-known-nodeinfo.json b/test/fixtures/mastodon-well-known-nodeinfo.json
new file mode 100644
index 000000000..237d5462a
--- /dev/null
+++ b/test/fixtures/mastodon-well-known-nodeinfo.json
@@ -0,0 +1 @@
+{"links":[{"rel":"http://nodeinfo.diaspora.software/ns/schema/2.0","href":"https://mastodon.example.org/nodeinfo/2.0"}]} \ No newline at end of file
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/fixtures/wildebeest-nodeinfo21.json b/test/fixtures/wildebeest-nodeinfo21.json
new file mode 100644
index 000000000..c6af474bf
--- /dev/null
+++ b/test/fixtures/wildebeest-nodeinfo21.json
@@ -0,0 +1 @@
+{"version":"2.1","software":{"name":"wildebeest","version":"0.0.1","repository":"https://github.com/cloudflare/wildebeest"},"protocols":["activitypub"],"usage":{"users":{"total":1,"activeMonth":1,"activeHalfyear":1}},"openRegistrations":false,"metadata":{"upstream":{"name":"mastodon","version":"3.5.1"}}} \ No newline at end of file
diff --git a/test/fixtures/wildebeest-well-known-nodeinfo.json b/test/fixtures/wildebeest-well-known-nodeinfo.json
new file mode 100644
index 000000000..c7ddb43af
--- /dev/null
+++ b/test/fixtures/wildebeest-well-known-nodeinfo.json
@@ -0,0 +1 @@
+{"links":[{"rel":"http://nodeinfo.diaspora.software/ns/schema/2.0","href":"https://wildebeest.example.org/nodeinfo/2.0"},{"rel":"http://nodeinfo.diaspora.software/ns/schema/2.1","href":"https://wildebeest.example.org/nodeinfo/2.1"}]} \ No newline at end of file
diff --git a/test/fixtures/xml_billion_laughs.xml b/test/fixtures/xml_billion_laughs.xml
new file mode 100644
index 000000000..75fb24cae
--- /dev/null
+++ b/test/fixtures/xml_billion_laughs.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!DOCTYPE lolz [
+ <!ENTITY lol "lol">
+ <!ELEMENT lolz (#PCDATA)>
+ <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
+ <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
+ <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
+ <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
+ <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
+ <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
+ <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
+ <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
+ <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
+]>
+<lolz>&lol9;</lolz>
diff --git a/test/mix/tasks/pleroma/openapi_spec_test.exs b/test/mix/tasks/pleroma/openapi_spec_test.exs
new file mode 100644
index 000000000..01437187a
--- /dev/null
+++ b/test/mix/tasks/pleroma/openapi_spec_test.exs
@@ -0,0 +1,62 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Mix.Tasks.Pleroma.OpenapiSpecTest do
+ use Pleroma.DataCase, async: true
+
+ alias Mix.Tasks.Pleroma.OpenapiSpec
+
+ @spec_base %{
+ "paths" => %{
+ "/cofe" => %{
+ "get" => %{
+ "operationId" => "Some.operation",
+ "tags" => []
+ }
+ },
+ "/mew" => %{
+ "post" => %{
+ "operationId" => "Another.operation",
+ "tags" => ["mew mew"]
+ }
+ }
+ },
+ "x-tagGroups" => [
+ %{
+ "name" => "mew",
+ "tags" => ["mew mew", "abc"]
+ },
+ %{
+ "name" => "lol",
+ "tags" => ["lol lol", "xyz"]
+ }
+ ]
+ }
+
+ describe "check_specs/1" do
+ test "Every operation must have a tag" do
+ assert {:error, ["Some.operation (get /cofe): No tags specified"]} ==
+ OpenapiSpec.check_specs(@spec_base)
+ end
+
+ test "Every tag must be in tag groups" do
+ spec =
+ @spec_base
+ |> put_in(["paths", "/cofe", "get", "tags"], ["abc", "def", "not specified"])
+
+ assert {:error,
+ [
+ "Some.operation (get /cofe): Tags #{inspect(["def", "not specified"])} not available. Please add it in \"x-tagGroups\" in Pleroma.Web.ApiSpec"
+ ]} == OpenapiSpec.check_specs(spec)
+ end
+
+ test "No errors if ok" do
+ spec =
+ @spec_base
+ |> put_in(["paths", "/cofe", "get", "tags"], ["abc", "mew mew"])
+
+ assert :ok == OpenapiSpec.check_specs(spec)
+ end
+ end
+end
diff --git a/test/pleroma/bbs/handler_test.exs b/test/pleroma/bbs/handler_test.exs
deleted file mode 100644
index aea3b6ead..000000000
--- a/test/pleroma/bbs/handler_test.exs
+++ /dev/null
@@ -1,89 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.BBS.HandlerTest do
- use Pleroma.DataCase, async: true
- alias Pleroma.Activity
- alias Pleroma.BBS.Handler
- alias Pleroma.Object
- alias Pleroma.Repo
- alias Pleroma.User
- alias Pleroma.Web.CommonAPI
-
- import ExUnit.CaptureIO
- import Pleroma.Factory
- import Ecto.Query
-
- test "getting the home timeline" do
- user = insert(:user)
- followed = insert(:user)
-
- {:ok, user, followed} = User.follow(user, followed)
-
- {:ok, _first} = CommonAPI.post(user, %{status: "hey"})
- {:ok, _second} = CommonAPI.post(followed, %{status: "hello"})
-
- output =
- capture_io(fn ->
- Handler.handle_command(%{user: user}, "home")
- end)
-
- assert output =~ user.nickname
- assert output =~ followed.nickname
-
- assert output =~ "hey"
- assert output =~ "hello"
- end
-
- test "posting" do
- user = insert(:user)
-
- output =
- capture_io(fn ->
- Handler.handle_command(%{user: user}, "p this is a test post")
- end)
-
- assert output =~ "Posted"
-
- activity =
- Repo.one(
- from(a in Activity,
- where: fragment("?->>'type' = ?", a.data, "Create")
- )
- )
-
- assert activity.actor == user.ap_id
- object = Object.normalize(activity, fetch: false)
- assert object.data["content"] == "this is a test post"
- end
-
- test "replying" do
- user = insert(:user)
- another_user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(another_user, %{status: "this is a test post"})
- activity_object = Object.normalize(activity, fetch: false)
-
- output =
- capture_io(fn ->
- Handler.handle_command(%{user: user}, "r #{activity.id} this is a reply")
- end)
-
- assert output =~ "Replied"
-
- reply =
- Repo.one(
- from(a in Activity,
- where: fragment("?->>'type' = ?", a.data, "Create"),
- where: a.actor == ^user.ap_id
- )
- )
-
- assert reply.actor == user.ap_id
-
- reply_object_data = Object.normalize(reply, fetch: false).data
- assert reply_object_data["content"] == "this is a reply"
- assert reply_object_data["inReplyTo"] == activity_object.data["id"]
- end
-end
diff --git a/test/pleroma/config/release_runtime_provider_test.exs b/test/pleroma/config/release_runtime_provider_test.exs
index 8ff578e63..8d2a93d6c 100644
--- a/test/pleroma/config/release_runtime_provider_test.exs
+++ b/test/pleroma/config/release_runtime_provider_test.exs
@@ -10,7 +10,7 @@ defmodule Pleroma.Config.ReleaseRuntimeProviderTest do
describe "load/2" do
test "loads release defaults config and warns about non-existent runtime config" do
ExUnit.CaptureIO.capture_io(fn ->
- merged = ReleaseRuntimeProvider.load([], [])
+ merged = ReleaseRuntimeProvider.load([], config_path: "/var/empty/config.exs")
assert merged == Pleroma.Config.Holder.release_defaults()
end) =~
"!!! Config path is not declared! Please ensure it exists and that PLEROMA_CONFIG_PATH is unset or points to an existing file"
diff --git a/test/pleroma/ecto_type/activity_pub/object_validators/bare_uri_test.ex b/test/pleroma/ecto_type/activity_pub/object_validators/bare_uri_test.ex
new file mode 100644
index 000000000..226383c3c
--- /dev/null
+++ b/test/pleroma/ecto_type/activity_pub/object_validators/bare_uri_test.ex
@@ -0,0 +1,25 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.BareUriTest do
+ use Pleroma.DataCase, async: true
+
+ alias Pleroma.EctoType.ActivityPub.ObjectValidators.BareUri
+
+ test "diaspora://" do
+ text = "diaspora://alice@fediverse.example/post/deadbeefdeadbeefdeadbeefdeadbeef"
+ assert {:ok, text} = BareUri.cast(text)
+ end
+
+ test "nostr:" do
+ text = "nostr:note1gwdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
+ assert {:ok, text} = BareUri.cast(text)
+ end
+
+ test "errors for non-URIs" do
+ assert :error == SafeText.cast(1)
+ assert :error == SafeText.cast("foo")
+ assert :error == SafeText.cast("foo bar")
+ end
+end
diff --git a/test/pleroma/instances/instance_test.exs b/test/pleroma/instances/instance_test.exs
index 861519bce..a769f9362 100644
--- a/test/pleroma/instances/instance_test.exs
+++ b/test/pleroma/instances/instance_test.exs
@@ -161,6 +161,66 @@ defmodule Pleroma.Instances.InstanceTest do
end
end
+ describe "get_or_update_metadata/1" do
+ test "Scrapes Wildebeest NodeInfo" do
+ Tesla.Mock.mock(fn
+ %{url: "https://wildebeest.example.org/.well-known/nodeinfo"} ->
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/wildebeest-well-known-nodeinfo.json")
+ }
+
+ %{url: "https://wildebeest.example.org/nodeinfo/2.1"} ->
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/wildebeest-nodeinfo21.json")
+ }
+ end)
+
+ expected = %{
+ software_name: "wildebeest",
+ software_repository: "https://github.com/cloudflare/wildebeest",
+ software_version: "0.0.1"
+ }
+
+ assert expected ==
+ Instance.get_or_update_metadata(URI.parse("https://wildebeest.example.org/"))
+
+ expected = %Pleroma.Instances.Instance.Pleroma.Instances.Metadata{
+ software_name: "wildebeest",
+ software_repository: "https://github.com/cloudflare/wildebeest",
+ software_version: "0.0.1"
+ }
+
+ assert expected ==
+ Repo.get_by(Pleroma.Instances.Instance, %{host: "wildebeest.example.org"}).metadata
+ end
+
+ test "Scrapes Mastodon NodeInfo" do
+ Tesla.Mock.mock(fn
+ %{url: "https://mastodon.example.org/.well-known/nodeinfo"} ->
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/mastodon-well-known-nodeinfo.json")
+ }
+
+ %{url: "https://mastodon.example.org/nodeinfo/2.0"} ->
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/mastodon-nodeinfo20.json")
+ }
+ end)
+
+ expected = %{
+ software_name: "mastodon",
+ software_version: "4.1.0"
+ }
+
+ assert expected ==
+ Instance.get_or_update_metadata(URI.parse("https://mastodon.example.org/"))
+ end
+ end
+
test "delete_users_and_activities/1 deletes remote instance users and activities" do
[mario, luigi, _peach, wario] =
users = [
diff --git a/test/pleroma/integration/mastodon_websocket_test.exs b/test/pleroma/integration/mastodon_websocket_test.exs
index 9be0445c0..a2c20f0a6 100644
--- a/test/pleroma/integration/mastodon_websocket_test.exs
+++ b/test/pleroma/integration/mastodon_websocket_test.exs
@@ -31,9 +31,22 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
WebsocketClient.start_link(self(), path, headers)
end
+ defp decode_json(json) do
+ with {:ok, %{"event" => event, "payload" => payload_text}} <- Jason.decode(json),
+ {:ok, payload} <- Jason.decode(payload_text) do
+ {:ok, %{"event" => event, "payload" => payload}}
+ end
+ end
+
+ # Turns atom keys to strings
+ defp atom_key_to_string(json) do
+ json
+ |> Jason.encode!()
+ |> Jason.decode!()
+ end
+
test "refuses invalid requests" do
capture_log(fn ->
- assert {:error, %WebSockex.RequestError{code: 404}} = start_socket()
assert {:error, %WebSockex.RequestError{code: 404}} = start_socket("?stream=ncjdk")
Process.sleep(30)
end)
@@ -49,6 +62,10 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
end)
end
+ test "allows unified stream" do
+ assert {:ok, _} = start_socket()
+ end
+
test "allows public streams without authentication" do
assert {:ok, _} = start_socket("?stream=public")
assert {:ok, _} = start_socket("?stream=public:local")
@@ -70,12 +87,143 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
view_json =
Pleroma.Web.MastodonAPI.StatusView.render("show.json", activity: activity, for: nil)
- |> Jason.encode!()
- |> Jason.decode!()
+ |> atom_key_to_string()
assert json == view_json
end
+ describe "subscribing via WebSocket" do
+ test "can subscribe" do
+ user = insert(:user)
+ {:ok, pid} = start_socket()
+ WebsocketClient.send_text(pid, %{type: "subscribe", stream: "public"} |> Jason.encode!())
+ assert_receive {:text, raw_json}, 1_000
+
+ assert {:ok,
+ %{
+ "event" => "pleroma:respond",
+ "payload" => %{"type" => "subscribe", "result" => "success"}
+ }} = decode_json(raw_json)
+
+ {:ok, activity} = CommonAPI.post(user, %{status: "nice echo chamber"})
+
+ assert_receive {:text, raw_json}, 1_000
+ assert {:ok, json} = Jason.decode(raw_json)
+
+ assert "update" == json["event"]
+ assert json["payload"]
+ assert {:ok, json} = Jason.decode(json["payload"])
+
+ view_json =
+ Pleroma.Web.MastodonAPI.StatusView.render("show.json", activity: activity, for: nil)
+ |> Jason.encode!()
+ |> Jason.decode!()
+
+ assert json == view_json
+ end
+
+ test "can subscribe to multiple streams" do
+ user = insert(:user)
+ {:ok, pid} = start_socket()
+ WebsocketClient.send_text(pid, %{type: "subscribe", stream: "public"} |> Jason.encode!())
+ assert_receive {:text, raw_json}, 1_000
+
+ assert {:ok,
+ %{
+ "event" => "pleroma:respond",
+ "payload" => %{"type" => "subscribe", "result" => "success"}
+ }} = decode_json(raw_json)
+
+ WebsocketClient.send_text(
+ pid,
+ %{type: "subscribe", stream: "hashtag", tag: "mew"} |> Jason.encode!()
+ )
+
+ assert_receive {:text, raw_json}, 1_000
+
+ assert {:ok,
+ %{
+ "event" => "pleroma:respond",
+ "payload" => %{"type" => "subscribe", "result" => "success"}
+ }} = decode_json(raw_json)
+
+ {:ok, _activity} = CommonAPI.post(user, %{status: "nice echo chamber #mew"})
+
+ assert_receive {:text, raw_json}, 1_000
+ assert {:ok, %{"stream" => stream1}} = Jason.decode(raw_json)
+ assert_receive {:text, raw_json}, 1_000
+ assert {:ok, %{"stream" => stream2}} = Jason.decode(raw_json)
+
+ streams = [stream1, stream2]
+ assert ["hashtag", "mew"] in streams
+ assert ["public"] in streams
+ end
+
+ test "won't double subscribe" do
+ user = insert(:user)
+ {:ok, pid} = start_socket()
+ WebsocketClient.send_text(pid, %{type: "subscribe", stream: "public"} |> Jason.encode!())
+ assert_receive {:text, raw_json}, 1_000
+
+ assert {:ok,
+ %{
+ "event" => "pleroma:respond",
+ "payload" => %{"type" => "subscribe", "result" => "success"}
+ }} = decode_json(raw_json)
+
+ WebsocketClient.send_text(pid, %{type: "subscribe", stream: "public"} |> Jason.encode!())
+ assert_receive {:text, raw_json}, 1_000
+
+ assert {:ok,
+ %{
+ "event" => "pleroma:respond",
+ "payload" => %{"type" => "subscribe", "result" => "ignored"}
+ }} = decode_json(raw_json)
+
+ {:ok, _activity} = CommonAPI.post(user, %{status: "nice echo chamber"})
+
+ assert_receive {:text, _}, 1_000
+ refute_receive {:text, _}, 1_000
+ end
+
+ test "rejects invalid streams" do
+ {:ok, pid} = start_socket()
+ WebsocketClient.send_text(pid, %{type: "subscribe", stream: "nonsense"} |> Jason.encode!())
+ assert_receive {:text, raw_json}, 1_000
+
+ assert {:ok,
+ %{
+ "event" => "pleroma:respond",
+ "payload" => %{"type" => "subscribe", "result" => "error", "error" => "bad_topic"}
+ }} = decode_json(raw_json)
+ end
+
+ test "can unsubscribe" do
+ user = insert(:user)
+ {:ok, pid} = start_socket()
+ WebsocketClient.send_text(pid, %{type: "subscribe", stream: "public"} |> Jason.encode!())
+ assert_receive {:text, raw_json}, 1_000
+
+ assert {:ok,
+ %{
+ "event" => "pleroma:respond",
+ "payload" => %{"type" => "subscribe", "result" => "success"}
+ }} = decode_json(raw_json)
+
+ WebsocketClient.send_text(pid, %{type: "unsubscribe", stream: "public"} |> Jason.encode!())
+ assert_receive {:text, raw_json}, 1_000
+
+ assert {:ok,
+ %{
+ "event" => "pleroma:respond",
+ "payload" => %{"type" => "unsubscribe", "result" => "success"}
+ }} = decode_json(raw_json)
+
+ {:ok, _activity} = CommonAPI.post(user, %{status: "nice echo chamber"})
+ refute_receive {:text, _}, 1_000
+ end
+ end
+
describe "with a valid user token" do
setup do
{:ok, app} =
@@ -131,6 +279,124 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
end)
end
+ test "accepts valid token on client-sent event", %{token: token} do
+ assert {:ok, pid} = start_socket()
+
+ WebsocketClient.send_text(
+ pid,
+ %{type: "pleroma:authenticate", token: token.token} |> Jason.encode!()
+ )
+
+ assert_receive {:text, raw_json}, 1_000
+
+ assert {:ok,
+ %{
+ "event" => "pleroma:respond",
+ "payload" => %{"type" => "pleroma:authenticate", "result" => "success"}
+ }} = decode_json(raw_json)
+
+ WebsocketClient.send_text(pid, %{type: "subscribe", stream: "user"} |> Jason.encode!())
+ assert_receive {:text, raw_json}, 1_000
+
+ assert {:ok,
+ %{
+ "event" => "pleroma:respond",
+ "payload" => %{"type" => "subscribe", "result" => "success"}
+ }} = decode_json(raw_json)
+ end
+
+ test "rejects invalid token on client-sent event" do
+ assert {:ok, pid} = start_socket()
+
+ WebsocketClient.send_text(
+ pid,
+ %{type: "pleroma:authenticate", token: "Something else"} |> Jason.encode!()
+ )
+
+ assert_receive {:text, raw_json}, 1_000
+
+ assert {:ok,
+ %{
+ "event" => "pleroma:respond",
+ "payload" => %{
+ "type" => "pleroma:authenticate",
+ "result" => "error",
+ "error" => "unauthorized"
+ }
+ }} = decode_json(raw_json)
+ end
+
+ test "rejects new authenticate request if already logged-in", %{token: token} do
+ assert {:ok, pid} = start_socket()
+
+ WebsocketClient.send_text(
+ pid,
+ %{type: "pleroma:authenticate", token: token.token} |> Jason.encode!()
+ )
+
+ assert_receive {:text, raw_json}, 1_000
+
+ assert {:ok,
+ %{
+ "event" => "pleroma:respond",
+ "payload" => %{"type" => "pleroma:authenticate", "result" => "success"}
+ }} = decode_json(raw_json)
+
+ WebsocketClient.send_text(
+ pid,
+ %{type: "pleroma:authenticate", token: "Something else"} |> Jason.encode!()
+ )
+
+ assert_receive {:text, raw_json}, 1_000
+
+ assert {:ok,
+ %{
+ "event" => "pleroma:respond",
+ "payload" => %{
+ "type" => "pleroma:authenticate",
+ "result" => "error",
+ "error" => "already_authenticated"
+ }
+ }} = decode_json(raw_json)
+ end
+
+ test "accepts the 'list' stream", %{token: token, user: user} do
+ posting_user = insert(:user)
+
+ {:ok, list} = Pleroma.List.create("test", user)
+ Pleroma.List.follow(list, posting_user)
+
+ assert {:ok, _} = start_socket("?stream=list&access_token=#{token.token}&list=#{list.id}")
+
+ assert {:ok, pid} = start_socket("?access_token=#{token.token}")
+
+ WebsocketClient.send_text(
+ pid,
+ %{type: "subscribe", stream: "list", list: list.id} |> Jason.encode!()
+ )
+
+ assert_receive {:text, raw_json}, 1_000
+
+ assert {:ok,
+ %{
+ "event" => "pleroma:respond",
+ "payload" => %{"type" => "subscribe", "result" => "success"}
+ }} = decode_json(raw_json)
+
+ WebsocketClient.send_text(
+ pid,
+ %{type: "subscribe", stream: "list", list: to_string(list.id)} |> Jason.encode!()
+ )
+
+ assert_receive {:text, raw_json}, 1_000
+
+ assert {:ok,
+ %{
+ "event" => "pleroma:respond",
+ "payload" => %{"type" => "subscribe", "result" => "ignored"}
+ }} = decode_json(raw_json)
+ end
+
test "disconnect when token is revoked", %{app: app, user: user, token: token} do
assert {:ok, _} = start_socket("?stream=user:notification&access_token=#{token.token}")
assert {:ok, _} = start_socket("?stream=user&access_token=#{token.token}")
@@ -146,5 +412,85 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
assert_receive {:close, _}
refute_receive {:close, _}
end
+
+ test "receives private statuses", %{user: reading_user, token: token} do
+ user = insert(:user)
+ CommonAPI.follow(reading_user, user)
+
+ {:ok, _} = start_socket("?stream=user&access_token=#{token.token}")
+
+ {:ok, activity} =
+ CommonAPI.post(user, %{status: "nice echo chamber", visibility: "private"})
+
+ assert_receive {:text, raw_json}, 1_000
+ assert {:ok, json} = Jason.decode(raw_json)
+
+ assert "update" == json["event"]
+ assert json["payload"]
+ assert {:ok, json} = Jason.decode(json["payload"])
+
+ view_json =
+ Pleroma.Web.MastodonAPI.StatusView.render("show.json",
+ activity: activity,
+ for: reading_user
+ )
+ |> Jason.encode!()
+ |> Jason.decode!()
+
+ assert json == view_json
+ end
+
+ test "receives edits", %{user: reading_user, token: token} do
+ user = insert(:user)
+ CommonAPI.follow(reading_user, user)
+
+ {:ok, _} = start_socket("?stream=user&access_token=#{token.token}")
+
+ {:ok, activity} =
+ CommonAPI.post(user, %{status: "nice echo chamber", visibility: "private"})
+
+ assert_receive {:text, _raw_json}, 1_000
+
+ {:ok, _} = CommonAPI.update(user, activity, %{status: "mew mew", visibility: "private"})
+
+ assert_receive {:text, raw_json}, 1_000
+
+ activity = Pleroma.Activity.normalize(activity)
+
+ view_json =
+ Pleroma.Web.MastodonAPI.StatusView.render("show.json",
+ activity: activity,
+ for: reading_user
+ )
+ |> Jason.encode!()
+ |> Jason.decode!()
+
+ assert {:ok, %{"event" => "status.update", "payload" => ^view_json}} = decode_json(raw_json)
+ end
+
+ test "receives notifications", %{user: reading_user, token: token} do
+ user = insert(:user)
+ CommonAPI.follow(reading_user, user)
+
+ {:ok, _} = start_socket("?stream=user:notification&access_token=#{token.token}")
+
+ {:ok, %Pleroma.Activity{id: activity_id} = _activity} =
+ CommonAPI.post(user, %{
+ status: "nice echo chamber @#{reading_user.nickname}",
+ visibility: "private"
+ })
+
+ assert_receive {:text, raw_json}, 1_000
+
+ assert {:ok,
+ %{
+ "event" => "notification",
+ "payload" => %{
+ "status" => %{
+ "id" => ^activity_id
+ }
+ }
+ }} = decode_json(raw_json)
+ end
end
end
diff --git a/test/pleroma/notification_test.exs b/test/pleroma/notification_test.exs
index e55aa3a08..71af9acb8 100644
--- a/test/pleroma/notification_test.exs
+++ b/test/pleroma/notification_test.exs
@@ -252,7 +252,7 @@ defmodule Pleroma.NotificationTest do
task =
Task.async(fn ->
{:ok, _topic} = Streamer.get_topic_and_add_socket("user", user, oauth_token)
- assert_receive {:render_with_user, _, _, _}, 4_000
+ assert_receive {:render_with_user, _, _, _, _}, 4_000
end)
task_user_notification =
@@ -260,7 +260,7 @@ defmodule Pleroma.NotificationTest do
{:ok, _topic} =
Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
- assert_receive {:render_with_user, _, _, _}, 4_000
+ assert_receive {:render_with_user, _, _, _, _}, 4_000
end)
activity = insert(:note_activity)
diff --git a/test/pleroma/object_test.exs b/test/pleroma/object_test.exs
index d536e0b16..7bc5c9928 100644
--- a/test/pleroma/object_test.exs
+++ b/test/pleroma/object_test.exs
@@ -444,4 +444,42 @@ defmodule Pleroma.ObjectTest do
Enum.sort_by(object.hashtags, & &1.name)
end
end
+
+ describe "get_emoji_reactions/1" do
+ test "3-tuple current format" do
+ object = %Object{
+ data: %{
+ "reactions" => [
+ ["x", ["https://some/user"], "https://some/emoji"]
+ ]
+ }
+ }
+
+ assert Object.get_emoji_reactions(object) == object.data["reactions"]
+ end
+
+ test "2-tuple legacy format" do
+ object = %Object{
+ data: %{
+ "reactions" => [
+ ["x", ["https://some/user"]]
+ ]
+ }
+ }
+
+ assert Object.get_emoji_reactions(object) == [["x", ["https://some/user"], nil]]
+ end
+
+ test "Map format" do
+ object = %Object{
+ data: %{
+ "reactions" => %{
+ "x" => ["https://some/user"]
+ }
+ }
+ }
+
+ assert Object.get_emoji_reactions(object) == [["x", ["https://some/user"], nil]]
+ end
+ end
end
diff --git a/test/pleroma/upload/filter/only_media_test.exs b/test/pleroma/upload/filter/only_media_test.exs
new file mode 100644
index 000000000..75be070a1
--- /dev/null
+++ b/test/pleroma/upload/filter/only_media_test.exs
@@ -0,0 +1,32 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Upload.Filter.OnlyMediaTest do
+ use Pleroma.DataCase, async: true
+
+ alias Pleroma.Upload
+ alias Pleroma.Upload.Filter.OnlyMedia
+
+ test "Allows media Content-Type" do
+ ["audio/mpeg", "image/jpeg", "video/mp4"]
+ |> Enum.each(fn type ->
+ upload = %Upload{
+ content_type: type
+ }
+
+ assert {:ok, :noop} = OnlyMedia.filter(upload)
+ end)
+ end
+
+ test "Disallows non-media Content-Type" do
+ ["application/javascript", "application/pdf", "text/html"]
+ |> Enum.each(fn type ->
+ upload = %Upload{
+ content_type: type
+ }
+
+ assert {:error, _} = OnlyMedia.filter(upload)
+ end)
+ end
+end
diff --git a/test/pleroma/user/backup_test.exs b/test/pleroma/user/backup_test.exs
index 5c9b94000..066bf6ba8 100644
--- a/test/pleroma/user/backup_test.exs
+++ b/test/pleroma/user/backup_test.exs
@@ -39,7 +39,7 @@ defmodule Pleroma.User.BackupTest do
assert_enqueued(worker: BackupWorker, args: args)
backup = Backup.get(args["backup_id"])
- assert %Backup{user_id: ^user_id, processed: false, file_size: 0} = backup
+ assert %Backup{user_id: ^user_id, processed: false, file_size: 0, state: :pending} = backup
end
test "it return an error if the export limit is over" do
@@ -59,7 +59,30 @@ defmodule Pleroma.User.BackupTest do
assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id} = args}} = Backup.create(user)
assert {:ok, backup} = perform_job(BackupWorker, args)
assert backup.file_size > 0
- assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id} = backup
+ assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id, state: :complete} = backup
+
+ delete_job_args = %{"op" => "delete", "backup_id" => backup_id}
+
+ assert_enqueued(worker: BackupWorker, args: delete_job_args)
+ assert {:ok, backup} = perform_job(BackupWorker, delete_job_args)
+ refute Backup.get(backup_id)
+
+ email = Pleroma.Emails.UserEmail.backup_is_ready_email(backup)
+
+ assert_email_sent(
+ to: {user.name, user.email},
+ html_body: email.html_body
+ )
+ end
+
+ test "it updates states of the backup" do
+ clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
+ %{id: user_id} = user = insert(:user)
+
+ assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id} = args}} = Backup.create(user)
+ assert {:ok, backup} = perform_job(BackupWorker, args)
+ assert backup.file_size > 0
+ assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id, state: :complete} = backup
delete_job_args = %{"op" => "delete", "backup_id" => backup_id}
@@ -148,7 +171,7 @@ defmodule Pleroma.User.BackupTest do
Bookmark.create(user.id, status3.id)
assert {:ok, backup} = user |> Backup.new() |> Repo.insert()
- assert {:ok, path} = Backup.export(backup)
+ assert {:ok, path} = Backup.export(backup, self())
assert {:ok, zipfile} = :zip.zip_open(String.to_charlist(path), [:memory])
assert {:ok, {'actor.json', json}} = :zip.zip_get('actor.json', zipfile)
@@ -230,6 +253,73 @@ defmodule Pleroma.User.BackupTest do
File.rm!(path)
end
+ test "it counts the correct number processed" do
+ user = insert(:user, %{nickname: "cofe", name: "Cofe", ap_id: "http://cofe.io/users/cofe"})
+
+ Enum.map(1..120, fn i ->
+ {:ok, status} = CommonAPI.post(user, %{status: "status #{i}"})
+ CommonAPI.favorite(user, status.id)
+ Bookmark.create(user.id, status.id)
+ end)
+
+ assert {:ok, backup} = user |> Backup.new() |> Repo.insert()
+ {:ok, backup} = Backup.process(backup)
+
+ assert backup.processed_number == 1 + 120 + 120 + 120
+
+ Backup.delete(backup)
+ end
+
+ test "it handles errors" do
+ user = insert(:user, %{nickname: "cofe", name: "Cofe", ap_id: "http://cofe.io/users/cofe"})
+
+ Enum.map(1..120, fn i ->
+ {:ok, _status} = CommonAPI.post(user, %{status: "status #{i}"})
+ end)
+
+ assert {:ok, backup} = user |> Backup.new() |> Repo.insert()
+
+ with_mock Pleroma.Web.ActivityPub.Transmogrifier,
+ [:passthrough],
+ prepare_outgoing: fn data ->
+ object =
+ data["object"]
+ |> Pleroma.Object.normalize(fetch: false)
+ |> Map.get(:data)
+
+ data = data |> Map.put("object", object)
+
+ if String.contains?(data["object"]["content"], "119"),
+ do: raise(%Postgrex.Error{}),
+ else: {:ok, data}
+ end do
+ {:ok, backup} = Backup.process(backup)
+ assert backup.processed
+ assert backup.state == :complete
+ assert backup.processed_number == 1 + 119
+
+ Backup.delete(backup)
+ end
+ end
+
+ test "it handles unrecoverable exceptions" do
+ user = insert(:user, %{nickname: "cofe", name: "Cofe", ap_id: "http://cofe.io/users/cofe"})
+
+ assert {:ok, backup} = user |> Backup.new() |> Repo.insert()
+
+ with_mock Backup, [:passthrough], do_process: fn _, _ -> raise "mock exception" end do
+ {:error, %{backup: backup, reason: :exit}} = Backup.process(backup)
+
+ assert backup.state == :failed
+ end
+
+ with_mock Backup, [:passthrough], do_process: fn _, _ -> Process.sleep(:timer.seconds(32)) end do
+ {:error, %{backup: backup, reason: :timeout}} = Backup.process(backup)
+
+ assert backup.state == :failed
+ end
+ end
+
describe "it uploads and deletes a backup archive" do
setup do
clear_config([Pleroma.Upload, :base_url], "https://s3.amazonaws.com")
@@ -246,7 +336,7 @@ defmodule Pleroma.User.BackupTest do
Bookmark.create(user.id, status3.id)
assert {:ok, backup} = user |> Backup.new() |> Repo.insert()
- assert {:ok, path} = Backup.export(backup)
+ assert {:ok, path} = Backup.export(backup, self())
[path: path, backup: backup]
end
diff --git a/test/pleroma/user/import_test.exs b/test/pleroma/user/import_test.exs
index b4efd4bb0..f75305e0e 100644
--- a/test/pleroma/user/import_test.exs
+++ b/test/pleroma/user/import_test.exs
@@ -3,7 +3,6 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.User.ImportTest do
- alias Pleroma.Repo
alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
diff --git a/test/pleroma/user_search_test.exs b/test/pleroma/user_search_test.exs
index 1deab6888..1af9a1493 100644
--- a/test/pleroma/user_search_test.exs
+++ b/test/pleroma/user_search_test.exs
@@ -3,7 +3,6 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.UserSearchTest do
- alias Pleroma.Repo
alias Pleroma.User
use Pleroma.DataCase
diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs
index c16312a65..7f60b959a 100644
--- a/test/pleroma/user_test.exs
+++ b/test/pleroma/user_test.exs
@@ -1844,7 +1844,6 @@ defmodule Pleroma.UserTest do
confirmation_token: "qqqq",
domain_blocks: ["lain.com"],
is_active: false,
- ap_enabled: true,
is_moderator: true,
is_admin: true,
mascot: %{"a" => "b"},
@@ -1885,7 +1884,6 @@ defmodule Pleroma.UserTest do
confirmation_token: nil,
domain_blocks: [],
is_active: false,
- ap_enabled: false,
is_moderator: false,
is_admin: false,
mascot: nil,
@@ -2473,8 +2471,7 @@ defmodule Pleroma.UserTest do
insert(:user,
local: false,
follower_address: "http://localhost:4001/users/masto_closed/followers",
- following_address: "http://localhost:4001/users/masto_closed/following",
- ap_enabled: true
+ following_address: "http://localhost:4001/users/masto_closed/following"
)
assert other_user.following_count == 0
@@ -2495,8 +2492,7 @@ defmodule Pleroma.UserTest do
insert(:user,
local: false,
follower_address: "http://localhost:4001/users/masto_closed/followers",
- following_address: "http://localhost:4001/users/masto_closed/following",
- ap_enabled: true
+ following_address: "http://localhost:4001/users/masto_closed/following"
)
assert other_user.following_count == 0
@@ -2517,8 +2513,7 @@ defmodule Pleroma.UserTest do
insert(:user,
local: false,
follower_address: "http://localhost:4001/users/masto_closed/followers",
- following_address: "http://localhost:4001/users/masto_closed/following",
- ap_enabled: true
+ following_address: "http://localhost:4001/users/masto_closed/following"
)
assert other_user.following_count == 0
diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
index ef91066c1..62eb9b5a3 100644
--- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
+++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
@@ -575,7 +575,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
user =
insert(:user,
ap_id: "https://mastodon.example.org/users/raymoo",
- ap_enabled: true,
local: false,
last_refreshed_at: nil
)
diff --git a/test/pleroma/web/activity_pub/activity_pub_test.exs b/test/pleroma/web/activity_pub/activity_pub_test.exs
index a6f8b6152..1e8c14043 100644
--- a/test/pleroma/web/activity_pub/activity_pub_test.exs
+++ b/test/pleroma/web/activity_pub/activity_pub_test.exs
@@ -174,7 +174,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, user} = ActivityPub.make_user_from_ap_id(user_id)
assert user.ap_id == user_id
assert user.nickname == "admin@mastodon.example.org"
- assert user.ap_enabled
assert user.follower_address == "http://mastodon.example.org/users/admin/followers"
end
@@ -2653,4 +2652,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, user} = ActivityPub.make_user_from_ap_id("https://princess.cat/users/mewmew")
assert user.name == " "
end
+
+ test "pin_data_from_featured_collection will ignore unsupported values" do
+ assert %{} ==
+ ActivityPub.pin_data_from_featured_collection(%{
+ "type" => "OrderedCollection",
+ "first" => "https://social.example/users/alice/collections/featured?page=true"
+ })
+ end
end
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/emoji_policy_test.exs b/test/pleroma/web/activity_pub/mrf/emoji_policy_test.exs
new file mode 100644
index 000000000..7350800f0
--- /dev/null
+++ b/test/pleroma/web/activity_pub/mrf/emoji_policy_test.exs
@@ -0,0 +1,425 @@
+# 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.EmojiPolicyTest do
+ use Pleroma.DataCase
+
+ require Pleroma.Constants
+
+ alias Pleroma.Web.ActivityPub.MRF
+ alias Pleroma.Web.ActivityPub.MRF.EmojiPolicy
+
+ setup do: clear_config(:mrf_emoji)
+
+ setup do
+ clear_config([:mrf_emoji], %{
+ remove_url: [],
+ remove_shortcode: [],
+ federated_timeline_removal_url: [],
+ federated_timeline_removal_shortcode: []
+ })
+ end
+
+ @emoji_tags [
+ %{
+ "icon" => %{
+ "type" => "Image",
+ "url" => "https://example.org/emoji/biribiri/mikoto_smile2.png"
+ },
+ "id" => "https://example.org/emoji/biribiri/mikoto_smile2.png",
+ "name" => ":mikoto_smile2:",
+ "type" => "Emoji",
+ "updated" => "1970-01-01T00:00:00Z"
+ },
+ %{
+ "icon" => %{
+ "type" => "Image",
+ "url" => "https://example.org/emoji/biribiri/mikoto_smile3.png"
+ },
+ "id" => "https://example.org/emoji/biribiri/mikoto_smile3.png",
+ "name" => ":mikoto_smile3:",
+ "type" => "Emoji",
+ "updated" => "1970-01-01T00:00:00Z"
+ },
+ %{
+ "icon" => %{
+ "type" => "Image",
+ "url" => "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
+ },
+ "id" => "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png",
+ "name" => ":nekomimi_girl_emoji_007:",
+ "type" => "Emoji",
+ "updated" => "1970-01-01T00:00:00Z"
+ },
+ %{
+ "icon" => %{
+ "type" => "Image",
+ "url" => "https://example.org/test.png"
+ },
+ "id" => "https://example.org/test.png",
+ "name" => ":test:",
+ "type" => "Emoji",
+ "updated" => "1970-01-01T00:00:00Z"
+ }
+ ]
+
+ @misc_tags [%{"type" => "Placeholder"}]
+
+ @user_data %{
+ "type" => "Person",
+ "id" => "https://example.org/placeholder",
+ "name" => "lol",
+ "tag" => @emoji_tags ++ @misc_tags
+ }
+
+ @status_data %{
+ "type" => "Create",
+ "object" => %{
+ "type" => "Note",
+ "id" => "https://example.org/placeholder",
+ "content" => "lol",
+ "tag" => @emoji_tags ++ @misc_tags,
+ "emoji" => %{
+ "mikoto_smile2" => "https://example.org/emoji/biribiri/mikoto_smile2.png",
+ "mikoto_smile3" => "https://example.org/emoji/biribiri/mikoto_smile3.png",
+ "nekomimi_girl_emoji_007" =>
+ "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png",
+ "test" => "https://example.org/test.png"
+ },
+ "to" => ["https://example.org/self", Pleroma.Constants.as_public()],
+ "cc" => ["https://example.org/someone"]
+ },
+ "to" => ["https://example.org/self", Pleroma.Constants.as_public()],
+ "cc" => ["https://example.org/someone"]
+ }
+
+ @status_data_with_history %{
+ "type" => "Create",
+ "object" =>
+ @status_data["object"]
+ |> Map.merge(%{
+ "formerRepresentations" => %{
+ "type" => "OrderedCollection",
+ "orderedItems" => [@status_data["object"] |> Map.put("content", "older")],
+ "totalItems" => 1
+ }
+ }),
+ "to" => ["https://example.org/self", Pleroma.Constants.as_public()],
+ "cc" => ["https://example.org/someone"]
+ }
+
+ @emoji_react_data %{
+ "type" => "EmojiReact",
+ "tag" => [@emoji_tags |> Enum.at(3)],
+ "object" => "https://example.org/someobject",
+ "to" => ["https://example.org/self"],
+ "cc" => ["https://example.org/someone"]
+ }
+
+ @emoji_react_data_matching_regex %{
+ "type" => "EmojiReact",
+ "tag" => [@emoji_tags |> Enum.at(1)],
+ "object" => "https://example.org/someobject",
+ "to" => ["https://example.org/self"],
+ "cc" => ["https://example.org/someone"]
+ }
+
+ @emoji_react_data_matching_nothing %{
+ "type" => "EmojiReact",
+ "tag" => [@emoji_tags |> Enum.at(2)],
+ "object" => "https://example.org/someobject",
+ "to" => ["https://example.org/self"],
+ "cc" => ["https://example.org/someone"]
+ }
+
+ @emoji_react_data_unicode %{
+ "type" => "EmojiReact",
+ "content" => "😍",
+ "object" => "https://example.org/someobject",
+ "to" => ["https://example.org/self"],
+ "cc" => ["https://example.org/someone"]
+ }
+
+ describe "remove_url" do
+ setup do
+ clear_config([:mrf_emoji, :remove_url], [
+ "https://example.org/test.png",
+ ~r{/biribiri/mikoto_smile[23]\.png},
+ "nekomimi_girl_emoji"
+ ])
+
+ :ok
+ end
+
+ test "processes user" do
+ {:ok, filtered} = MRF.filter_one(EmojiPolicy, @user_data)
+
+ expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
+
+ assert %{"tag" => ^expected_tags} = filtered
+ end
+
+ test "processes status" do
+ {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data)
+
+ expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
+
+ expected_emoji = %{
+ "nekomimi_girl_emoji_007" =>
+ "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
+ }
+
+ assert %{"object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}} = filtered
+ end
+
+ test "processes status with history" do
+ {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data_with_history)
+
+ expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
+
+ expected_emoji = %{
+ "nekomimi_girl_emoji_007" =>
+ "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
+ }
+
+ assert %{
+ "object" => %{
+ "tag" => ^expected_tags,
+ "emoji" => ^expected_emoji,
+ "formerRepresentations" => %{"orderedItems" => [item]}
+ }
+ } = filtered
+
+ assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item
+ end
+
+ test "processes updates" do
+ {:ok, filtered} =
+ MRF.filter_one(EmojiPolicy, @status_data_with_history |> Map.put("type", "Update"))
+
+ expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
+
+ expected_emoji = %{
+ "nekomimi_girl_emoji_007" =>
+ "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
+ }
+
+ assert %{
+ "object" => %{
+ "tag" => ^expected_tags,
+ "emoji" => ^expected_emoji,
+ "formerRepresentations" => %{"orderedItems" => [item]}
+ }
+ } = filtered
+
+ assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item
+ end
+
+ test "processes EmojiReact" do
+ assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} ==
+ MRF.filter_one(EmojiPolicy, @emoji_react_data)
+
+ assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} ==
+ MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_regex)
+
+ assert {:ok, @emoji_react_data_matching_nothing} ==
+ MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_nothing)
+
+ assert {:ok, @emoji_react_data_unicode} ==
+ MRF.filter_one(EmojiPolicy, @emoji_react_data_unicode)
+ end
+ end
+
+ describe "remove_shortcode" do
+ setup do
+ clear_config([:mrf_emoji, :remove_shortcode], [
+ "test",
+ ~r{mikoto_s},
+ "nekomimi_girl_emoji"
+ ])
+
+ :ok
+ end
+
+ test "processes user" do
+ {:ok, filtered} = MRF.filter_one(EmojiPolicy, @user_data)
+
+ expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
+
+ assert %{"tag" => ^expected_tags} = filtered
+ end
+
+ test "processes status" do
+ {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data)
+
+ expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
+
+ expected_emoji = %{
+ "nekomimi_girl_emoji_007" =>
+ "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
+ }
+
+ assert %{"object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}} = filtered
+ end
+
+ test "processes status with history" do
+ {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data_with_history)
+
+ expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
+
+ expected_emoji = %{
+ "nekomimi_girl_emoji_007" =>
+ "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
+ }
+
+ assert %{
+ "object" => %{
+ "tag" => ^expected_tags,
+ "emoji" => ^expected_emoji,
+ "formerRepresentations" => %{"orderedItems" => [item]}
+ }
+ } = filtered
+
+ assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item
+ end
+
+ test "processes updates" do
+ {:ok, filtered} =
+ MRF.filter_one(EmojiPolicy, @status_data_with_history |> Map.put("type", "Update"))
+
+ expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
+
+ expected_emoji = %{
+ "nekomimi_girl_emoji_007" =>
+ "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
+ }
+
+ assert %{
+ "object" => %{
+ "tag" => ^expected_tags,
+ "emoji" => ^expected_emoji,
+ "formerRepresentations" => %{"orderedItems" => [item]}
+ }
+ } = filtered
+
+ assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item
+ end
+
+ test "processes EmojiReact" do
+ assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} ==
+ MRF.filter_one(EmojiPolicy, @emoji_react_data)
+
+ assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} ==
+ MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_regex)
+
+ assert {:ok, @emoji_react_data_matching_nothing} ==
+ MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_nothing)
+
+ assert {:ok, @emoji_react_data_unicode} ==
+ MRF.filter_one(EmojiPolicy, @emoji_react_data_unicode)
+ end
+ end
+
+ describe "federated_timeline_removal_url" do
+ setup do
+ clear_config([:mrf_emoji, :federated_timeline_removal_url], [
+ "https://example.org/test.png",
+ ~r{/biribiri/mikoto_smile[23]\.png},
+ "nekomimi_girl_emoji"
+ ])
+
+ :ok
+ end
+
+ test "processes status" do
+ {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data)
+
+ expected_tags = @status_data["object"]["tag"]
+ expected_emoji = @status_data["object"]["emoji"]
+
+ expected_to = ["https://example.org/self"]
+ expected_cc = [Pleroma.Constants.as_public(), "https://example.org/someone"]
+
+ assert %{
+ "to" => ^expected_to,
+ "cc" => ^expected_cc,
+ "object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}
+ } = filtered
+ end
+
+ test "ignore updates" do
+ {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data |> Map.put("type", "Update"))
+
+ expected_tags = @status_data["object"]["tag"]
+ expected_emoji = @status_data["object"]["emoji"]
+
+ expected_to = ["https://example.org/self", Pleroma.Constants.as_public()]
+ expected_cc = ["https://example.org/someone"]
+
+ assert %{
+ "to" => ^expected_to,
+ "cc" => ^expected_cc,
+ "object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}
+ } = filtered
+ end
+
+ test "processes status with history" do
+ status =
+ @status_data_with_history
+ |> put_in(["object", "tag"], @misc_tags)
+ |> put_in(["object", "emoji"], %{})
+
+ {:ok, filtered} = MRF.filter_one(EmojiPolicy, status)
+
+ expected_tags = @status_data["object"]["tag"]
+ expected_emoji = @status_data["object"]["emoji"]
+
+ expected_to = ["https://example.org/self"]
+ expected_cc = [Pleroma.Constants.as_public(), "https://example.org/someone"]
+
+ assert %{
+ "to" => ^expected_to,
+ "cc" => ^expected_cc,
+ "object" => %{
+ "formerRepresentations" => %{
+ "orderedItems" => [%{"tag" => ^expected_tags, "emoji" => ^expected_emoji}]
+ }
+ }
+ } = filtered
+ end
+ end
+
+ describe "edge cases" do
+ setup do
+ clear_config([:mrf_emoji, :remove_url], [
+ "https://example.org/test.png",
+ ~r{/biribiri/mikoto_smile[23]\.png},
+ "nekomimi_girl_emoji"
+ ])
+
+ :ok
+ end
+
+ test "non-statuses" do
+ answer = @status_data |> put_in(["object", "type"], "Answer")
+ {:ok, filtered} = MRF.filter_one(EmojiPolicy, answer)
+
+ assert filtered == answer
+ end
+
+ test "without tag" do
+ status = @status_data |> Map.put("object", Map.drop(@status_data["object"], ["tag"]))
+ {:ok, filtered} = MRF.filter_one(EmojiPolicy, status)
+
+ refute Map.has_key?(filtered["object"], "tag")
+ end
+
+ test "without emoji" do
+ status = @status_data |> Map.put("object", Map.drop(@status_data["object"], ["emoji"]))
+ {:ok, filtered} = MRF.filter_one(EmojiPolicy, status)
+
+ refute Map.has_key?(filtered["object"], "emoji")
+ end
+ end
+end
diff --git a/test/pleroma/web/activity_pub/mrf/force_mentions_in_content_test.exs b/test/pleroma/web/activity_pub/mrf/force_mentions_in_content_test.exs
index b349a4bb7..811ef105c 100644
--- a/test/pleroma/web/activity_pub/mrf/force_mentions_in_content_test.exs
+++ b/test/pleroma/web/activity_pub/mrf/force_mentions_in_content_test.exs
@@ -256,4 +256,55 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContentTest do
}
}} = MRF.filter_one(ForceMentionsInContent, activity)
end
+
+ test "don't add duplicate mentions for mastodon or misskey posts" do
+ [zero, rogerick, greg] = [
+ insert(:user,
+ ap_id: "https://pleroma.example.com/users/zero",
+ uri: "https://pleroma.example.com/users/zero",
+ nickname: "zero@pleroma.example.com",
+ local: false
+ ),
+ insert(:user,
+ ap_id: "https://misskey.example.com/users/104ab42f11",
+ uri: "https://misskey.example.com/@rogerick",
+ nickname: "rogerick@misskey.example.com",
+ local: false
+ ),
+ insert(:user,
+ ap_id: "https://mastodon.example.com/users/greg",
+ uri: "https://mastodon.example.com/@greg",
+ nickname: "greg@mastodon.example.com",
+ local: false
+ )
+ ]
+
+ {:ok, post} = CommonAPI.post(rogerick, %{status: "eugh"})
+
+ inline_mentions = [
+ "<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{rogerick.id}\" href=\"#{rogerick.ap_id}\" rel=\"ugc\">@<span>rogerick</span></a></span>",
+ "<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{greg.id}\" href=\"#{greg.uri}\" rel=\"ugc\">@<span>greg</span></a></span>"
+ ]
+
+ activity = %{
+ "type" => "Create",
+ "actor" => zero.ap_id,
+ "object" => %{
+ "type" => "Note",
+ "actor" => zero.ap_id,
+ "content" => "#{Enum.at(inline_mentions, 0)} #{Enum.at(inline_mentions, 1)} erm",
+ "to" => [
+ rogerick.ap_id,
+ greg.ap_id,
+ Constants.as_public()
+ ],
+ "inReplyTo" => Object.normalize(post).data["id"]
+ }
+ }
+
+ {:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity)
+
+ assert filtered ==
+ "#{Enum.at(inline_mentions, 0)} #{Enum.at(inline_mentions, 1)} erm"
+ 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/mrf/utils_test.exs b/test/pleroma/web/activity_pub/mrf/utils_test.exs
new file mode 100644
index 000000000..3bbc2cfd3
--- /dev/null
+++ b/test/pleroma/web/activity_pub/mrf/utils_test.exs
@@ -0,0 +1,19 @@
+# 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.UtilsTest do
+ use Pleroma.DataCase, async: true
+
+ alias Pleroma.Web.ActivityPub.MRF.Utils
+
+ describe "describe_regex_or_string/1" do
+ test "describes regex" do
+ assert "~r/foo/i" == Utils.describe_regex_or_string(~r/foo/i)
+ end
+
+ test "returns string as-is" do
+ assert "foo" == Utils.describe_regex_or_string("foo")
+ end
+ 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/object_validators/emoji_react_handling_test.exs b/test/pleroma/web/activity_pub/object_validators/emoji_react_handling_test.exs
index bbdb09c4c..9bb291a38 100644
--- a/test/pleroma/web/activity_pub/object_validators/emoji_react_handling_test.exs
+++ b/test/pleroma/web/activity_pub/object_validators/emoji_react_handling_test.exs
@@ -38,16 +38,70 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactHandlingTest do
assert {:content, {"can't be blank", [validation: :required]}} in cng.errors
end
- test "it is not valid with a non-emoji content field", %{valid_emoji_react: valid_emoji_react} do
+ test "it is valid when custom emoji is used", %{valid_emoji_react: valid_emoji_react} do
without_emoji_content =
valid_emoji_react
- |> Map.put("content", "x")
+ |> Map.put("content", ":hello:")
+ |> Map.put("tag", [
+ %{
+ "type" => "Emoji",
+ "name" => ":hello:",
+ "icon" => %{"url" => "http://somewhere", "type" => "Image"}
+ }
+ ])
+
+ {:ok, _, _} = ObjectValidator.validate(without_emoji_content, [])
+ end
+
+ test "it is not valid when custom emoji don't have a matching tag", %{
+ valid_emoji_react: valid_emoji_react
+ } do
+ without_emoji_content =
+ valid_emoji_react
+ |> Map.put("content", ":hello:")
+ |> Map.put("tag", [
+ %{
+ "type" => "Emoji",
+ "name" => ":whoops:",
+ "icon" => %{"url" => "http://somewhere", "type" => "Image"}
+ }
+ ])
+
+ {:error, cng} = ObjectValidator.validate(without_emoji_content, [])
+
+ refute cng.valid?
+
+ assert {:tag, {"does not contain an Emoji tag", []}} in cng.errors
+ end
+
+ test "it is not valid when custom emoji have no tags", %{
+ valid_emoji_react: valid_emoji_react
+ } do
+ without_emoji_content =
+ valid_emoji_react
+ |> Map.put("content", ":hello:")
+ |> Map.put("tag", [])
+
+ {:error, cng} = ObjectValidator.validate(without_emoji_content, [])
+
+ refute cng.valid?
+
+ assert {:tag, {"does not contain an Emoji tag", []}} in cng.errors
+ end
+
+ test "it is not valid when custom emoji doesn't match a shortcode format", %{
+ valid_emoji_react: valid_emoji_react
+ } do
+ without_emoji_content =
+ valid_emoji_react
+ |> Map.put("content", "hello")
+ |> Map.put("tag", [])
{:error, cng} = ObjectValidator.validate(without_emoji_content, [])
refute cng.valid?
- assert {:content, {"must be a single character emoji", []}} in cng.errors
+ assert {:tag, {"does not contain an Emoji tag", []}} in cng.errors
end
end
end
diff --git a/test/pleroma/web/activity_pub/publisher_test.exs b/test/pleroma/web/activity_pub/publisher_test.exs
index e2db3d575..c5137cbb7 100644
--- a/test/pleroma/web/activity_pub/publisher_test.exs
+++ b/test/pleroma/web/activity_pub/publisher_test.exs
@@ -276,8 +276,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
follower =
insert(:user, %{
local: false,
- inbox: "https://domain.com/users/nick1/inbox",
- ap_enabled: true
+ inbox: "https://domain.com/users/nick1/inbox"
})
actor = insert(:user, follower_address: follower.ap_id)
@@ -313,8 +312,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
follower =
insert(:user, %{
local: false,
- inbox: "https://domain.com/users/nick1/inbox",
- ap_enabled: true
+ inbox: "https://domain.com/users/nick1/inbox"
})
actor = insert(:user, follower_address: follower.ap_id)
@@ -348,8 +346,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
follower =
insert(:user, %{
local: false,
- inbox: "https://domain.com/users/nick1/inbox",
- ap_enabled: true
+ inbox: "https://domain.com/users/nick1/inbox"
})
actor = insert(:user, follower_address: follower.ap_id)
@@ -382,15 +379,13 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
fetcher =
insert(:user,
local: false,
- inbox: "https://domain.com/users/nick1/inbox",
- ap_enabled: true
+ inbox: "https://domain.com/users/nick1/inbox"
)
another_fetcher =
insert(:user,
local: false,
- inbox: "https://domain2.com/users/nick1/inbox",
- ap_enabled: true
+ inbox: "https://domain2.com/users/nick1/inbox"
)
actor = insert(:user)
diff --git a/test/pleroma/web/activity_pub/side_effects_test.exs b/test/pleroma/web/activity_pub/side_effects_test.exs
index b24831e85..6820e23d0 100644
--- a/test/pleroma/web/activity_pub/side_effects_test.exs
+++ b/test/pleroma/web/activity_pub/side_effects_test.exs
@@ -453,7 +453,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
object = Object.get_by_ap_id(emoji_react.data["object"])
assert object.data["reaction_count"] == 1
- assert ["👌", [user.ap_id]] in object.data["reactions"]
+ assert ["👌", [user.ap_id], nil] in object.data["reactions"]
end
test "creates a notification", %{emoji_react: emoji_react, poster: poster} do
diff --git a/test/pleroma/web/activity_pub/transmogrifier/emoji_react_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/emoji_react_handling_test.exs
index 83bf59c6f..f2e1cefa3 100644
--- a/test/pleroma/web/activity_pub/transmogrifier/emoji_react_handling_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier/emoji_react_handling_test.exs
@@ -34,7 +34,56 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.EmojiReactHandlingTest do
object = Object.get_by_ap_id(data["object"])
assert object.data["reaction_count"] == 1
- assert match?([["👌", _]], object.data["reactions"])
+ assert match?([["👌", _, nil]], object.data["reactions"])
+ end
+
+ test "it works for incoming custom emoji reactions" do
+ user = insert(:user)
+ other_user = insert(:user, local: false)
+ {:ok, activity} = CommonAPI.post(user, %{status: "hello"})
+
+ data =
+ File.read!("test/fixtures/custom-emoji-reaction.json")
+ |> Jason.decode!()
+ |> Map.put("object", activity.data["object"])
+ |> Map.put("actor", other_user.ap_id)
+
+ {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
+
+ assert data["actor"] == other_user.ap_id
+ assert data["type"] == "EmojiReact"
+ assert data["id"] == "https://misskey.local.live/likes/917ocsybgp"
+ assert data["object"] == activity.data["object"]
+ assert data["content"] == ":hanapog:"
+
+ assert data["tag"] == [
+ %{
+ "id" => "https://misskey.local.live/emojis/hanapog",
+ "type" => "Emoji",
+ "name" => "hanapog",
+ "updated" => "2022-06-07T12:00:05.773Z",
+ "icon" => %{
+ "type" => "Image",
+ "url" =>
+ "https://misskey.local.live/files/webpublic-8f8a9768-7264-4171-88d6-2356aabeadcd"
+ }
+ }
+ ]
+
+ object = Object.get_by_ap_id(data["object"])
+
+ assert object.data["reaction_count"] == 1
+
+ assert match?(
+ [
+ [
+ "hanapog",
+ _,
+ "https://misskey.local.live/files/webpublic-8f8a9768-7264-4171-88d6-2356aabeadcd"
+ ]
+ ],
+ object.data["reactions"]
+ )
end
test "it works for incoming unqualified emoji reactions" do
@@ -65,7 +114,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.EmojiReactHandlingTest do
object = Object.get_by_ap_id(data["object"])
assert object.data["reaction_count"] == 1
- assert match?([[^emoji, _]], object.data["reactions"])
+ assert match?([[^emoji, _, _]], object.data["reactions"])
end
test "it reject invalid emoji reactions" do
diff --git a/test/pleroma/web/activity_pub/transmogrifier/image_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/image_handling_test.exs
new file mode 100644
index 000000000..b85f0a477
--- /dev/null
+++ b/test/pleroma/web/activity_pub/transmogrifier/image_handling_test.exs
@@ -0,0 +1,50 @@
+# 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.Transmogrifier.ImageHandlingTest do
+ use Oban.Testing, repo: Pleroma.Repo
+ use Pleroma.DataCase
+
+ alias Pleroma.Activity
+ alias Pleroma.Object
+ alias Pleroma.Web.ActivityPub.Transmogrifier
+
+ test "Hubzilla Image object" do
+ Tesla.Mock.mock(fn
+ %{url: "https://hub.somaton.com/channel/testc6"} ->
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/hubzilla-actor.json"),
+ headers: HttpRequestMock.activitypub_object_headers()
+ }
+ end)
+
+ data = File.read!("test/fixtures/hubzilla-create-image.json") |> Poison.decode!()
+
+ {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
+
+ assert object = Object.normalize(activity, fetch: false)
+
+ assert object.data["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
+
+ assert object.data["cc"] == ["https://hub.somaton.com/followers/testc6"]
+
+ assert object.data["attachment"] == [
+ %{
+ "mediaType" => "image/jpeg",
+ "type" => "Link",
+ "url" => [
+ %{
+ "height" => 2200,
+ "href" =>
+ "https://hub.somaton.com/photo/452583b2-7e1f-4ac3-8334-ff666f134afe-0.jpg",
+ "mediaType" => "image/jpeg",
+ "type" => "Link",
+ "width" => 2200
+ }
+ ]
+ }
+ ]
+ end
+end
diff --git a/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs
index 7c406fbd0..a9ad3e9c8 100644
--- a/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs
@@ -104,6 +104,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
end
end
+ @tag capture_log: true
test "it does not crash if the object in inReplyTo can't be fetched" do
data =
File.read!("test/fixtures/mastodon-post-activity.json")
@@ -723,6 +724,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
assert modified.data["context"] == object.data["id"]
end
+ @tag capture_log: true
test "the reply note uses its parent's ID when context is missing and reply is unreachable" do
insert(:user, ap_id: "https://mk.absturztau.be/users/8ozbzjs3o8")
diff --git a/test/pleroma/web/activity_pub/transmogrifier_test.exs b/test/pleroma/web/activity_pub/transmogrifier_test.exs
index 6b4636d22..5e58d75db 100644
--- a/test/pleroma/web/activity_pub/transmogrifier_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier_test.exs
@@ -8,7 +8,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
alias Pleroma.Activity
alias Pleroma.Object
- alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.ActivityPub.Utils
@@ -123,6 +122,39 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert activity.data["context"] == object.data["context"]
end
+
+ 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!()
+
+ assert {:ok, activity} = Transmogrifier.handle_incoming(message)
+
+ object = Object.normalize(activity)
+ 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)
+
+ # 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
describe "prepare outgoing" do
@@ -337,68 +369,19 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
}
} = prepared["object"]
end
- end
-
- describe "user upgrade" do
- test "it upgrades a user to activitypub" do
- user =
- insert(:user, %{
- nickname: "rye@niu.moe",
- local: false,
- ap_id: "https://niu.moe/users/rye",
- follower_address: User.ap_followers(%User{nickname: "rye@niu.moe"})
- })
-
- user_two = insert(:user)
- Pleroma.FollowingRelationship.follow(user_two, user, :follow_accept)
- {:ok, activity} = CommonAPI.post(user, %{status: "test"})
- {:ok, unrelated_activity} = CommonAPI.post(user_two, %{status: "test"})
- assert "http://localhost:4001/users/rye@niu.moe/followers" in activity.recipients
-
- user = User.get_cached_by_id(user.id)
- assert user.note_count == 1
-
- {:ok, user} = Transmogrifier.upgrade_user_from_ap_id("https://niu.moe/users/rye")
- ObanHelpers.perform_all()
-
- assert user.ap_enabled
- assert user.note_count == 1
- assert user.follower_address == "https://niu.moe/users/rye/followers"
- assert user.following_address == "https://niu.moe/users/rye/following"
+ test "it prepares a quote post" do
+ user = insert(:user)
- user = User.get_cached_by_id(user.id)
- assert user.note_count == 1
+ {:ok, quoted_post} = CommonAPI.post(user, %{status: "hey"})
+ {:ok, quote_post} = CommonAPI.post(user, %{status: "hey", quote_id: quoted_post.id})
- activity = Activity.get_by_id(activity.id)
- assert user.follower_address in activity.recipients
+ {:ok, modified} = Transmogrifier.prepare_outgoing(quote_post.data)
- assert %{
- "url" => [
- %{
- "href" =>
- "https://cdn.niu.moe/accounts/avatars/000/033/323/original/fd7f8ae0b3ffedc9.jpeg"
- }
- ]
- } = user.avatar
+ %{data: %{"id" => quote_id}} = Object.normalize(quoted_post)
- assert %{
- "url" => [
- %{
- "href" =>
- "https://cdn.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
- }
- ]
- } = user.banner
-
- refute "..." in activity.recipients
-
- unrelated_activity = Activity.get_by_id(unrelated_activity.id)
- refute user.follower_address in unrelated_activity.recipients
-
- user_two = User.get_cached_by_id(user_two.id)
- assert User.following?(user_two, user)
- refute "..." in User.following(user_two)
+ assert modified["object"]["quoteUrl"] == quote_id
+ assert modified["object"]["quoteUri"] == quote_id
end
end
diff --git a/test/pleroma/web/activity_pub/utils_test.exs b/test/pleroma/web/activity_pub/utils_test.exs
index e7d1e01c4..3f93c872b 100644
--- a/test/pleroma/web/activity_pub/utils_test.exs
+++ b/test/pleroma/web/activity_pub/utils_test.exs
@@ -587,15 +587,38 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
end
describe "get_cached_emoji_reactions/1" do
- test "returns the data or an emtpy list" do
+ test "returns the normalized data or an emtpy list" do
object = insert(:note)
assert Utils.get_cached_emoji_reactions(object) == []
object = insert(:note, data: %{"reactions" => [["x", ["lain"]]]})
- assert Utils.get_cached_emoji_reactions(object) == [["x", ["lain"]]]
+ assert Utils.get_cached_emoji_reactions(object) == [["x", ["lain"], nil]]
object = insert(:note, data: %{"reactions" => %{}})
assert Utils.get_cached_emoji_reactions(object) == []
end
end
+
+ describe "add_emoji_reaction_to_object/1" do
+ test "works with legacy 2-tuple format" do
+ user = insert(:user)
+ other_user = insert(:user)
+ third_user = insert(:user)
+
+ note =
+ insert(:note,
+ user: user,
+ data: %{
+ "reactions" => [["😿", [other_user.ap_id]]]
+ }
+ )
+
+ _activity = insert(:note_activity, user: user, note: note)
+
+ Utils.add_emoji_reaction_to_object(
+ %Activity{data: %{"content" => "😿", "actor" => third_user.ap_id}},
+ note
+ )
+ end
+ end
end
diff --git a/test/pleroma/web/admin_api/controllers/config_controller_test.exs b/test/pleroma/web/admin_api/controllers/config_controller_test.exs
index 9ef7c0c46..19ce3681c 100644
--- a/test/pleroma/web/admin_api/controllers/config_controller_test.exs
+++ b/test/pleroma/web/admin_api/controllers/config_controller_test.exs
@@ -316,6 +316,7 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
assert Application.get_env(:idna, :key5) == {"string", Pleroma.Captcha.NotReal, []}
end
+ @tag capture_log: true
test "save configs setting without explicit key", %{conn: conn} do
adapter = Application.get_env(:http, :adapter)
send_user_agent = Application.get_env(:http, :send_user_agent)
@@ -1501,15 +1502,14 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
clear_config(:database_config_whitelist, [
{:pleroma, :instance},
{:pleroma, :activitypub},
- {:pleroma, Pleroma.Upload},
- {:esshd}
+ {:pleroma, Pleroma.Upload}
])
conn = get(conn, "/api/pleroma/admin/config/descriptions")
children = json_response_and_validate_schema(conn, 200)
- assert length(children) == 4
+ assert length(children) == 3
assert Enum.count(children, fn c -> c["group"] == ":pleroma" end) == 3
@@ -1521,9 +1521,6 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
web_endpoint = Enum.find(children, fn c -> c["key"] == "Pleroma.Upload" end)
assert web_endpoint["children"]
-
- esshd = Enum.find(children, fn c -> c["group"] == ":esshd" end)
- assert esshd["children"]
end
end
end
diff --git a/test/pleroma/web/admin_api/controllers/frontend_controller_test.exs b/test/pleroma/web/admin_api/controllers/frontend_controller_test.exs
index 38a23b224..0d1a4999e 100644
--- a/test/pleroma/web/admin_api/controllers/frontend_controller_test.exs
+++ b/test/pleroma/web/admin_api/controllers/frontend_controller_test.exs
@@ -89,6 +89,7 @@ defmodule Pleroma.Web.AdminAPI.FrontendControllerTest do
"build_url" => "http://gensokyo.2hu/builds/${ref}",
"git" => nil,
"installed" => true,
+ "installed_refs" => ["fantasy"],
"name" => "pleroma",
"ref" => "fantasy"
}
diff --git a/test/pleroma/web/admin_api/controllers/report_controller_test.exs b/test/pleroma/web/admin_api/controllers/report_controller_test.exs
index c141cf69d..fb2579a3d 100644
--- a/test/pleroma/web/admin_api/controllers/report_controller_test.exs
+++ b/test/pleroma/web/admin_api/controllers/report_controller_test.exs
@@ -123,6 +123,7 @@ defmodule Pleroma.Web.AdminAPI.ReportControllerTest do
})
%{
+ reporter: reporter,
id: report_id,
second_report_id: second_report_id
}
@@ -266,6 +267,26 @@ defmodule Pleroma.Web.AdminAPI.ReportControllerTest do
assert ModerationLog.get_log_entry_message(second_log_entry) ==
"@#{admin.nickname} updated report ##{second_report_id} (on user @#{second_activity.user_actor.nickname}) with 'closed' state"
end
+
+ test "works if reporter is deactivated", %{
+ conn: conn,
+ id: id,
+ reporter: reporter
+ } do
+ Pleroma.User.set_activation(reporter, false)
+
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> patch("/api/pleroma/admin/reports", %{
+ "reports" => [
+ %{"state" => "resolved", "id" => id}
+ ]
+ })
+ |> json_response_and_validate_schema(:no_content)
+
+ activity = Activity.get_by_id_with_user_actor(id)
+ assert activity.data["state"] == "resolved"
+ end
end
describe "GET /api/pleroma/admin/reports" do
diff --git a/test/pleroma/web/api_spec/scopes/compiler_test.exs b/test/pleroma/web/api_spec/scopes/compiler_test.exs
new file mode 100644
index 000000000..99e1d343a
--- /dev/null
+++ b/test/pleroma/web/api_spec/scopes/compiler_test.exs
@@ -0,0 +1,56 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ApiSpec.Scopes.CompilerTest do
+ use ExUnit.Case, async: true
+
+ alias Pleroma.Web.ApiSpec.Scopes.Compiler
+
+ @dummy_response %{}
+
+ @data %{
+ paths: %{
+ "/mew" => %OpenApiSpex.PathItem{
+ post: %OpenApiSpex.Operation{
+ security: [%{"oAuth" => ["a:b:c"]}],
+ responses: @dummy_response
+ },
+ get: %OpenApiSpex.Operation{security: nil, responses: @dummy_response}
+ },
+ "/mew2" => %OpenApiSpex.PathItem{
+ post: %OpenApiSpex.Operation{
+ security: [%{"oAuth" => ["d:e", "f:g"]}],
+ responses: @dummy_response
+ },
+ get: %OpenApiSpex.Operation{security: nil, responses: @dummy_response}
+ }
+ }
+ }
+
+ describe "process_scope/1" do
+ test "gives all higher-level scopes" do
+ scopes = Compiler.process_scope("admin:read:accounts")
+
+ assert [_, _, _] = scopes
+ assert "admin" in scopes
+ assert "admin:read" in scopes
+ assert "admin:read:accounts" in scopes
+ end
+ end
+
+ describe "extract_all_scopes_from/1" do
+ test "extracts scopes" do
+ scopes = Compiler.extract_all_scopes_from(@data)
+
+ assert [_, _, _, _, _, _, _] = scopes
+ assert "a" in scopes
+ assert "a:b" in scopes
+ assert "a:b:c" in scopes
+ assert "d" in scopes
+ assert "d:e" in scopes
+ assert "f" in scopes
+ assert "f:g" in scopes
+ end
+ end
+end
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/utils_test.exs b/test/pleroma/web/common_api/utils_test.exs
index c52d3e9c5..27b1da1e3 100644
--- a/test/pleroma/web/common_api/utils_test.exs
+++ b/test/pleroma/web/common_api/utils_test.exs
@@ -200,7 +200,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
{result, _, []} = Utils.format_input(code, "text/markdown")
assert result ==
- ~s[<p><span class="h-card"><a class="u-url mention" data-user="#{mario.id}" href="#{mario.ap_id}" rel="ugc">@<span>mario</span></a></span> <span class="h-card"><a class="u-url mention" data-user="#{luigi.id}" href="#{luigi.ap_id}" rel="ugc">@<span>luigi</span></a></span> yo what’s up?</p>]
+ ~s[<p><span class="h-card"><a class="u-url mention" data-user="#{mario.id}" href="#{mario.ap_id}" rel="ugc">@<span>mario</span></a></span> <span class="h-card"><a class="u-url mention" data-user="#{luigi.id}" href="#{luigi.ap_id}" rel="ugc">@<span>luigi</span></a></span> yo what&#39;s up?</p>]
end
test "remote mentions" do
@@ -211,7 +211,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
{result, _, []} = Utils.format_input(code, "text/markdown")
assert result ==
- ~s[<p><span class="h-card"><a class="u-url mention" data-user="#{mario.id}" href="#{mario.ap_id}" rel="ugc">@<span>mario</span></a></span> <span class="h-card"><a class="u-url mention" data-user="#{luigi.id}" href="#{luigi.ap_id}" rel="ugc">@<span>luigi</span></a></span> yo what’s up?</p>]
+ ~s[<p><span class="h-card"><a class="u-url mention" data-user="#{mario.id}" href="#{mario.ap_id}" rel="ugc">@<span>mario</span></a></span> <span class="h-card"><a class="u-url mention" data-user="#{luigi.id}" href="#{luigi.ap_id}" rel="ugc">@<span>luigi</span></a></span> yo what&#39;s up?</p>]
end
test "raw HTML" do
@@ -229,7 +229,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
test "blockquote" do
code = ~s[> whoms't are you quoting?]
{result, [], []} = Utils.format_input(code, "text/markdown")
- assert result == "<blockquote><p>whoms’t are you quoting?</p></blockquote>"
+ assert result == "<blockquote><p>whoms&#39;t are you quoting?</p></blockquote>"
end
test "code" do
@@ -593,7 +593,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
test "returns list attachments with desc" do
user = insert(:user)
- object = insert(:note, %{user: user})
+ object = insert(:attachment, %{user: user})
desc = Jason.encode!(%{object.id => "test-desc"})
assert Utils.attachments_from_ids_descs(["#{object.id}", "34"], desc, user) == [
@@ -605,7 +605,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
describe "attachments_from_ids/2" do
test "returns attachments with descs" do
user = insert(:user)
- object = insert(:note, %{user: user})
+ object = insert(:attachment, %{user: user})
desc = Jason.encode!(%{object.id => "test-desc"})
assert Utils.attachments_from_ids(
@@ -621,7 +621,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
test "returns attachments without descs" do
user = insert(:user)
- object = insert(:note, %{user: user})
+ object = insert(:attachment, %{user: user})
assert Utils.attachments_from_ids(%{media_ids: ["#{object.id}"]}, user) == [object.data]
end
@@ -637,6 +637,11 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
assert Utils.attachments_from_ids(%{media_ids: ["#{object.id}"]}, user2) == []
end
+
+ test "checks that the object is of upload type" do
+ object = insert(:note)
+ assert Utils.attachments_from_ids(%{media_ids: ["#{object.id}"]}, nil) == []
+ end
end
describe "maybe_add_list_data/3" do
diff --git a/test/pleroma/web/common_api_test.exs b/test/pleroma/web/common_api_test.exs
index e60691995..b21dd4e23 100644
--- a/test/pleroma/web/common_api_test.exs
+++ b/test/pleroma/web/common_api_test.exs
@@ -411,6 +411,20 @@ defmodule Pleroma.Web.CommonAPITest do
refute Activity.get_by_id(post.id)
end
+
+ test "it allows privileged users to delete banned user's posts" do
+ clear_config([:instance, :moderator_privileges], [:messages_delete])
+ user = insert(:user)
+ moderator = insert(:user, is_moderator: true)
+
+ {:ok, post} = CommonAPI.post(user, %{status: "namu amida butsu"})
+ User.set_activation(user, false)
+
+ assert {:ok, delete} = CommonAPI.delete(post.id, moderator)
+ assert delete.local
+
+ refute Activity.get_by_id(post.id)
+ end
end
test "favoriting race condition" do
@@ -545,6 +559,17 @@ defmodule Pleroma.Web.CommonAPITest do
assert Object.tags(object) == ["ساٴين‌س"]
end
+ test "allows lang attribute" do
+ user = insert(:user)
+ text = ~s{<span lang="en">something</span><p lang="diaetuitech_rpyhpgc">random</p>}
+
+ {:ok, activity} = CommonAPI.post(user, %{status: text, content_type: "text/html"})
+
+ object = Object.normalize(activity, fetch: false)
+
+ assert object.data["content"] == text
+ end
+
test "double dot in link is allowed" do
user = insert(:user)
text = "https://example.to/something..mp3"
@@ -771,6 +796,65 @@ 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
+
+ test "it properly mentions punycode domain" do
+ user = insert(:user)
+
+ _mentioned_user =
+ insert(:user, ap_id: "https://xn--i2raa.com/users/yyy", nickname: "yyy@xn--i2raa.com")
+
+ {:ok, activity} =
+ CommonAPI.post(user, %{status: "hey @yyy@xn--i2raa.com", content_type: "text/markdown"})
+
+ assert "https://xn--i2raa.com/users/yyy" in Object.normalize(activity).data["to"]
+ end
end
describe "reactions" do
@@ -1346,7 +1430,7 @@ defmodule Pleroma.Web.CommonAPITest do
test "cancels a pending follow for a remote user" do
follower = insert(:user)
- followed = insert(:user, is_locked: true, local: false, ap_enabled: true)
+ followed = insert(:user, is_locked: true, local: false)
assert {:ok, follower, followed, %{id: activity_id, data: %{"state" => "pending"}}} =
CommonAPI.follow(follower, followed)
diff --git a/test/pleroma/web/federator_test.exs b/test/pleroma/web/federator_test.exs
index 1ffe6aae1..6826e6c2f 100644
--- a/test/pleroma/web/federator_test.exs
+++ b/test/pleroma/web/federator_test.exs
@@ -78,16 +78,14 @@ defmodule Pleroma.Web.FederatorTest do
local: false,
nickname: "nick1@domain.com",
ap_id: "https://domain.com/users/nick1",
- inbox: inbox1,
- ap_enabled: true
+ inbox: inbox1
})
insert(:user, %{
local: false,
nickname: "nick2@domain2.com",
ap_id: "https://domain2.com/users/nick2",
- inbox: inbox2,
- ap_enabled: true
+ inbox: inbox2
})
dt = NaiveDateTime.utc_now()
diff --git a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs
index 958b7f76f..128e60b0a 100644
--- a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs
@@ -2031,6 +2031,39 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
assert [%{"id" => ^id1}] = result
end
+ test "list of blocks with with_relationships parameter" do
+ %{user: user, conn: conn} = oauth_access(["read:blocks"])
+ %{id: id1} = other_user1 = insert(:user)
+ %{id: id2} = other_user2 = insert(:user)
+ %{id: id3} = other_user3 = insert(:user)
+
+ {:ok, _, _} = User.follow(other_user1, user)
+ {:ok, _, _} = User.follow(other_user2, user)
+ {:ok, _, _} = User.follow(other_user3, user)
+
+ {:ok, _} = User.block(user, other_user1)
+ {:ok, _} = User.block(user, other_user2)
+ {:ok, _} = User.block(user, other_user3)
+
+ assert [
+ %{
+ "id" => ^id3,
+ "pleroma" => %{"relationship" => %{"blocking" => true, "followed_by" => false}}
+ },
+ %{
+ "id" => ^id2,
+ "pleroma" => %{"relationship" => %{"blocking" => true, "followed_by" => false}}
+ },
+ %{
+ "id" => ^id1,
+ "pleroma" => %{"relationship" => %{"blocking" => true, "followed_by" => false}}
+ }
+ ] =
+ conn
+ |> get("/api/v1/blocks?with_relationships=true")
+ |> json_response_and_validate_schema(200)
+ end
+
test "account lookup", %{conn: conn} do
%{nickname: acct} = insert(:user, %{nickname: "nickname"})
%{nickname: acct_two} = insert(:user, %{nickname: "nickname@notlocaldoma.in"})
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 5bae2cd00..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
@@ -626,7 +648,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|> put_req_header("content-type", "application/json")
|> post("/api/v1/statuses", %{
"status" => "desu~",
- "poll" => %{"options" => Enum.map(0..limit, fn _ -> "desu" end), "expires_in" => 1}
+ "poll" => %{
+ "options" => Enum.map(0..limit, fn num -> "desu #{num}" end),
+ "expires_in" => 1
+ }
})
%{"error" => error} = json_response_and_validate_schema(conn, 422)
@@ -642,7 +667,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|> post("/api/v1/statuses", %{
"status" => "...",
"poll" => %{
- "options" => [Enum.reduce(0..limit, "", fn _, acc -> acc <> "." end)],
+ "options" => [String.duplicate(".", limit + 1), "lol"],
"expires_in" => 1
}
})
@@ -724,6 +749,32 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
assert object.data["type"] == "Question"
assert length(object.data["oneOf"]) == 3
end
+
+ test "cannot have only one option", %{conn: conn} do
+ conn =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/statuses", %{
+ "status" => "desu~",
+ "poll" => %{"options" => ["mew"], "expires_in" => 1}
+ })
+
+ %{"error" => error} = json_response_and_validate_schema(conn, 422)
+ assert error == "Poll must contain at least 2 options"
+ end
+
+ test "cannot have only duplicated options", %{conn: conn} do
+ conn =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/statuses", %{
+ "status" => "desu~",
+ "poll" => %{"options" => ["mew", "mew"], "expires_in" => 1}
+ })
+
+ %{"error" => error} = json_response_and_validate_schema(conn, 422)
+ assert error == "Poll must contain at least 2 options"
+ end
end
test "get a status" do
@@ -742,6 +793,49 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
{:ok, local: local, remote: remote}
end
+ defp local_and_remote_context_activities do
+ local_user_1 = insert(:user)
+ local_user_2 = insert(:user)
+ remote_user = insert(:user, local: false)
+
+ {:ok, %{id: id1, data: %{"context" => context}}} =
+ CommonAPI.post(local_user_1, %{status: "post"})
+
+ {:ok, %{id: id2} = post} =
+ CommonAPI.post(local_user_2, %{status: "local reply", in_reply_to_status_id: id1})
+
+ params = %{
+ "@context" => "https://www.w3.org/ns/activitystreams",
+ "actor" => remote_user.ap_id,
+ "type" => "Create",
+ "context" => context,
+ "id" => "#{remote_user.ap_id}/activities/1",
+ "inReplyTo" => post.data["id"],
+ "object" => %{
+ "type" => "Note",
+ "content" => "remote reply",
+ "context" => context,
+ "id" => "#{remote_user.ap_id}/objects/1",
+ "attributedTo" => remote_user.ap_id,
+ "to" => [
+ local_user_1.ap_id,
+ local_user_2.ap_id,
+ "https://www.w3.org/ns/activitystreams#Public"
+ ]
+ },
+ "to" => [
+ local_user_1.ap_id,
+ local_user_2.ap_id,
+ "https://www.w3.org/ns/activitystreams#Public"
+ ]
+ }
+
+ {:ok, job} = Pleroma.Web.Federator.incoming_ap_doc(params)
+ {:ok, remote_activity} = ObanHelpers.perform(job)
+
+ %{locals: [id1, id2], remote: remote_activity.id, context: context}
+ end
+
describe "status with restrict unauthenticated activities for local and remote" do
setup do: local_and_remote_activities()
@@ -928,6 +1022,230 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
end
end
+ describe "getting status contexts restricted unauthenticated for local and remote" do
+ setup do: local_and_remote_context_activities()
+
+ setup do: clear_config([:restrict_unauthenticated, :activities, :local], true)
+
+ setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true)
+
+ test "if user is unauthenticated", %{conn: conn, locals: [post_id, _]} do
+ res_conn = get(conn, "/api/v1/statuses/#{post_id}/context")
+
+ assert json_response_and_validate_schema(res_conn, 200) == %{
+ "ancestors" => [],
+ "descendants" => []
+ }
+ end
+
+ test "if user is unauthenticated reply", %{conn: conn, locals: [_, reply_id]} do
+ res_conn = get(conn, "/api/v1/statuses/#{reply_id}/context")
+
+ assert json_response_and_validate_schema(res_conn, 200) == %{
+ "ancestors" => [],
+ "descendants" => []
+ }
+ end
+
+ test "if user is authenticated", %{locals: [post_id, reply_id], remote: remote_reply_id} do
+ %{conn: conn} = oauth_access(["read"])
+ res_conn = get(conn, "/api/v1/statuses/#{post_id}/context")
+
+ %{"ancestors" => [], "descendants" => descendants} =
+ json_response_and_validate_schema(res_conn, 200)
+
+ descendant_ids =
+ descendants
+ |> Enum.map(& &1["id"])
+
+ assert reply_id in descendant_ids
+ assert remote_reply_id in descendant_ids
+ end
+
+ test "if user is authenticated reply", %{locals: [post_id, reply_id], remote: remote_reply_id} do
+ %{conn: conn} = oauth_access(["read"])
+ res_conn = get(conn, "/api/v1/statuses/#{reply_id}/context")
+
+ %{"ancestors" => ancestors, "descendants" => descendants} =
+ json_response_and_validate_schema(res_conn, 200)
+
+ ancestor_ids =
+ ancestors
+ |> Enum.map(& &1["id"])
+
+ descendant_ids =
+ descendants
+ |> Enum.map(& &1["id"])
+
+ assert post_id in ancestor_ids
+ assert remote_reply_id in descendant_ids
+ end
+ end
+
+ describe "getting status contexts restricted unauthenticated for local" do
+ setup do: local_and_remote_context_activities()
+
+ setup do: clear_config([:restrict_unauthenticated, :activities, :local], true)
+
+ setup do: clear_config([:restrict_unauthenticated, :activities, :remote], false)
+
+ test "if user is unauthenticated", %{
+ conn: conn,
+ locals: [post_id, reply_id],
+ remote: remote_reply_id
+ } do
+ res_conn = get(conn, "/api/v1/statuses/#{post_id}/context")
+
+ %{"ancestors" => [], "descendants" => descendants} =
+ json_response_and_validate_schema(res_conn, 200)
+
+ descendant_ids =
+ descendants
+ |> Enum.map(& &1["id"])
+
+ assert reply_id not in descendant_ids
+ assert remote_reply_id in descendant_ids
+ end
+
+ test "if user is unauthenticated reply", %{
+ conn: conn,
+ locals: [post_id, reply_id],
+ remote: remote_reply_id
+ } do
+ res_conn = get(conn, "/api/v1/statuses/#{reply_id}/context")
+
+ %{"ancestors" => ancestors, "descendants" => descendants} =
+ json_response_and_validate_schema(res_conn, 200)
+
+ ancestor_ids =
+ ancestors
+ |> Enum.map(& &1["id"])
+
+ descendant_ids =
+ descendants
+ |> Enum.map(& &1["id"])
+
+ assert post_id not in ancestor_ids
+ assert remote_reply_id in descendant_ids
+ end
+
+ test "if user is authenticated", %{locals: [post_id, reply_id], remote: remote_reply_id} do
+ %{conn: conn} = oauth_access(["read"])
+ res_conn = get(conn, "/api/v1/statuses/#{post_id}/context")
+
+ %{"ancestors" => [], "descendants" => descendants} =
+ json_response_and_validate_schema(res_conn, 200)
+
+ descendant_ids =
+ descendants
+ |> Enum.map(& &1["id"])
+
+ assert reply_id in descendant_ids
+ assert remote_reply_id in descendant_ids
+ end
+
+ test "if user is authenticated reply", %{locals: [post_id, reply_id], remote: remote_reply_id} do
+ %{conn: conn} = oauth_access(["read"])
+ res_conn = get(conn, "/api/v1/statuses/#{reply_id}/context")
+
+ %{"ancestors" => ancestors, "descendants" => descendants} =
+ json_response_and_validate_schema(res_conn, 200)
+
+ ancestor_ids =
+ ancestors
+ |> Enum.map(& &1["id"])
+
+ descendant_ids =
+ descendants
+ |> Enum.map(& &1["id"])
+
+ assert post_id in ancestor_ids
+ assert remote_reply_id in descendant_ids
+ end
+ end
+
+ describe "getting status contexts restricted unauthenticated for remote" do
+ setup do: local_and_remote_context_activities()
+
+ setup do: clear_config([:restrict_unauthenticated, :activities, :local], false)
+
+ setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true)
+
+ test "if user is unauthenticated", %{
+ conn: conn,
+ locals: [post_id, reply_id],
+ remote: remote_reply_id
+ } do
+ res_conn = get(conn, "/api/v1/statuses/#{post_id}/context")
+
+ %{"ancestors" => [], "descendants" => descendants} =
+ json_response_and_validate_schema(res_conn, 200)
+
+ descendant_ids =
+ descendants
+ |> Enum.map(& &1["id"])
+
+ assert reply_id in descendant_ids
+ assert remote_reply_id not in descendant_ids
+ end
+
+ test "if user is unauthenticated reply", %{
+ conn: conn,
+ locals: [post_id, reply_id],
+ remote: remote_reply_id
+ } do
+ res_conn = get(conn, "/api/v1/statuses/#{reply_id}/context")
+
+ %{"ancestors" => ancestors, "descendants" => descendants} =
+ json_response_and_validate_schema(res_conn, 200)
+
+ ancestor_ids =
+ ancestors
+ |> Enum.map(& &1["id"])
+
+ descendant_ids =
+ descendants
+ |> Enum.map(& &1["id"])
+
+ assert post_id in ancestor_ids
+ assert remote_reply_id not in descendant_ids
+ end
+
+ test "if user is authenticated", %{locals: [post_id, reply_id], remote: remote_reply_id} do
+ %{conn: conn} = oauth_access(["read"])
+ res_conn = get(conn, "/api/v1/statuses/#{post_id}/context")
+
+ %{"ancestors" => [], "descendants" => descendants} =
+ json_response_and_validate_schema(res_conn, 200)
+
+ reply_ids =
+ descendants
+ |> Enum.map(& &1["id"])
+
+ assert reply_id in reply_ids
+ assert remote_reply_id in reply_ids
+ end
+
+ test "if user is authenticated reply", %{locals: [post_id, reply_id], remote: remote_reply_id} do
+ %{conn: conn} = oauth_access(["read"])
+ res_conn = get(conn, "/api/v1/statuses/#{reply_id}/context")
+
+ %{"ancestors" => ancestors, "descendants" => descendants} =
+ json_response_and_validate_schema(res_conn, 200)
+
+ ancestor_ids =
+ ancestors
+ |> Enum.map(& &1["id"])
+
+ descendant_ids =
+ descendants
+ |> Enum.map(& &1["id"])
+
+ assert post_id in ancestor_ids
+ assert remote_reply_id in descendant_ids
+ end
+ end
+
describe "deleting a status" do
test "when you created it" do
%{user: author, conn: conn} = oauth_access(["write:statuses"])
@@ -989,6 +1307,27 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
refute Activity.get_by_id(activity.id)
end
+
+ test "when you're privileged and the user is banned", %{conn: conn} do
+ clear_config([:instance, :moderator_privileges], [:messages_delete])
+ posting_user = insert(:user, is_active: false)
+ refute posting_user.is_active
+ activity = insert(:note_activity, user: posting_user)
+ user = insert(:user, is_moderator: true)
+
+ res_conn =
+ conn
+ |> assign(:user, user)
+ |> assign(:token, insert(:oauth_token, user: user, scopes: ["write:statuses"]))
+ |> delete("/api/v1/statuses/#{activity.id}")
+
+ assert %{} = json_response_and_validate_schema(res_conn, 200)
+
+ assert ModerationLog |> Repo.one() |> ModerationLog.get_log_entry_message() ==
+ "@#{user.nickname} deleted status ##{activity.id}"
+
+ refute Activity.get_by_id(activity.id)
+ end
end
describe "reblogging" do
diff --git a/test/pleroma/web/mastodon_api/update_credentials_test.exs b/test/pleroma/web/mastodon_api/update_credentials_test.exs
index 40f79d103..45412bb34 100644
--- a/test/pleroma/web/mastodon_api/update_credentials_test.exs
+++ b/test/pleroma/web/mastodon_api/update_credentials_test.exs
@@ -97,6 +97,42 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
assert user.raw_bio == raw_bio
end
+ test "updating bio honours bio limit", %{conn: conn} do
+ bio_limit = Config.get([:instance, :user_bio_length], 5000)
+
+ raw_bio = String.duplicate(".", bio_limit + 1)
+
+ conn = patch(conn, "/api/v1/accounts/update_credentials", %{"note" => raw_bio})
+
+ assert %{"error" => "Bio is too long"} = json_response_and_validate_schema(conn, 413)
+ end
+
+ test "updating name honours name limit", %{conn: conn} do
+ name_limit = Config.get([:instance, :user_name_length], 100)
+
+ name = String.duplicate(".", name_limit + 1)
+
+ conn = patch(conn, "/api/v1/accounts/update_credentials", %{"display_name" => name})
+
+ assert %{"error" => "Name is too long"} = json_response_and_validate_schema(conn, 413)
+ end
+
+ test "when both name and bio exceeds the limit, display name error", %{conn: conn} do
+ name_limit = Config.get([:instance, :user_name_length], 100)
+ bio_limit = Config.get([:instance, :user_bio_length], 5000)
+
+ name = String.duplicate(".", name_limit + 1)
+ raw_bio = String.duplicate(".", bio_limit + 1)
+
+ conn =
+ patch(conn, "/api/v1/accounts/update_credentials", %{
+ "display_name" => name,
+ "note" => raw_bio
+ })
+
+ assert %{"error" => "Name is too long"} = json_response_and_validate_schema(conn, 413)
+ end
+
test "updates the user's locking status", %{conn: conn} do
conn = patch(conn, "/api/v1/accounts/update_credentials", %{locked: "true"})
@@ -375,7 +411,9 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
"pleroma_background_image" => new_background_oversized
})
- assert _user_response = json_response_and_validate_schema(res, 413)
+ assert %{"error" => "File is too large"} == json_response_and_validate_schema(res, 413)
+
+ user = Repo.get(User, user.id)
assert user.background == %{}
clear_config([:instance, :upload_limit], upload_limit)
@@ -593,17 +631,17 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
fields = [%{"name" => "foo", "value" => long_value}]
- assert %{"error" => "Invalid request"} ==
+ assert %{"error" => "One or more field entries are too long"} ==
conn
|> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
- |> json_response_and_validate_schema(403)
+ |> json_response_and_validate_schema(413)
fields = [%{"name" => long_name, "value" => "bar"}]
- assert %{"error" => "Invalid request"} ==
+ assert %{"error" => "One or more field entries are too long"} ==
conn
|> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
- |> json_response_and_validate_schema(403)
+ |> json_response_and_validate_schema(413)
clear_config([:instance, :max_account_fields], 1)
@@ -612,10 +650,10 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
%{"name" => "link", "value" => "cofe.io"}
]
- assert %{"error" => "Invalid request"} ==
+ assert %{"error" => "Too many field entries"} ==
conn
|> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
- |> json_response_and_validate_schema(403)
+ |> json_response_and_validate_schema(413)
end
end
diff --git a/test/pleroma/web/mastodon_api/views/notification_view_test.exs b/test/pleroma/web/mastodon_api/views/notification_view_test.exs
index 6ea894691..ddbe4557f 100644
--- a/test/pleroma/web/mastodon_api/views/notification_view_test.exs
+++ b/test/pleroma/web/mastodon_api/views/notification_view_test.exs
@@ -190,7 +190,47 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
emoji: "☕",
account: AccountView.render("show.json", %{user: other_user, for: user}),
status: StatusView.render("show.json", %{activity: activity, for: user}),
- created_at: Utils.to_masto_date(notification.inserted_at)
+ created_at: Utils.to_masto_date(notification.inserted_at),
+ emoji_url: nil
+ }
+
+ test_notifications_rendering([notification], user, [expected])
+ end
+
+ test "EmojiReact custom emoji notification" do
+ user = insert(:user)
+ other_user = insert(:user)
+
+ note =
+ insert(:note,
+ user: user,
+ data: %{
+ "reactions" => [
+ ["👍", [user.ap_id], nil],
+ ["dinosaur", [user.ap_id], "http://localhost:4001/emoji/dino walking.gif"]
+ ]
+ }
+ )
+
+ activity = insert(:note_activity, note: note, user: user)
+
+ {:ok, _activity} = CommonAPI.react_with_emoji(activity.id, other_user, "dinosaur")
+
+ activity = Repo.get(Activity, activity.id)
+
+ [notification] = Notification.for_user(user)
+
+ assert notification
+
+ expected = %{
+ id: to_string(notification.id),
+ pleroma: %{is_seen: false, is_muted: false},
+ type: "pleroma:emoji_reaction",
+ emoji: ":dinosaur:",
+ account: AccountView.render("show.json", %{user: other_user, for: user}),
+ status: StatusView.render("show.json", %{activity: activity, for: user}),
+ created_at: Utils.to_masto_date(notification.inserted_at),
+ emoji_url: "http://localhost:4001/emoji/dino walking.gif"
}
test_notifications_rendering([notification], user, [expected])
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 f76b115b7..baa9b32f5 100644
--- a/test/pleroma/web/mastodon_api/views/status_view_test.exs
+++ b/test/pleroma/web/mastodon_api/views/status_view_test.exs
@@ -35,16 +35,26 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
{:ok, activity} = CommonAPI.post(user, %{status: "dae cofe??"})
{:ok, _} = CommonAPI.react_with_emoji(activity.id, user, "☕")
+ {:ok, _} = CommonAPI.react_with_emoji(activity.id, user, ":dinosaur:")
{:ok, _} = CommonAPI.react_with_emoji(activity.id, third_user, "🍵")
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
+ {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, ":dinosaur:")
+
activity = Repo.get(Activity, activity.id)
status = StatusView.render("show.json", activity: activity)
assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
assert status[:pleroma][:emoji_reactions] == [
- %{name: "☕", count: 2, me: false},
- %{name: "🍵", count: 1, me: false}
+ %{name: "☕", count: 2, me: false, url: nil, account_ids: [other_user.id, user.id]},
+ %{
+ count: 2,
+ me: false,
+ name: "dinosaur",
+ url: "http://localhost:4001/emoji/dino walking.gif",
+ account_ids: [other_user.id, user.id]
+ },
+ %{name: "🍵", count: 1, me: false, url: nil, account_ids: [third_user.id]}
]
status = StatusView.render("show.json", activity: activity, for: user)
@@ -52,8 +62,36 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
assert status[:pleroma][:emoji_reactions] == [
- %{name: "☕", count: 2, me: true},
- %{name: "🍵", count: 1, me: false}
+ %{name: "☕", count: 2, me: true, url: nil, account_ids: [other_user.id, user.id]},
+ %{
+ count: 2,
+ me: true,
+ name: "dinosaur",
+ url: "http://localhost:4001/emoji/dino walking.gif",
+ account_ids: [other_user.id, user.id]
+ },
+ %{name: "🍵", count: 1, me: false, url: nil, account_ids: [third_user.id]}
+ ]
+ end
+
+ test "works with legacy-formatted reactions" do
+ user = insert(:user)
+ other_user = insert(:user)
+
+ note =
+ insert(:note,
+ user: user,
+ data: %{
+ "reactions" => [["😿", [other_user.ap_id]]]
+ }
+ )
+
+ activity = insert(:note_activity, user: user, note: note)
+
+ status = StatusView.render("show.json", activity: activity, for: user)
+
+ assert status[:pleroma][:emoji_reactions] == [
+ %{name: "😿", count: 1, me: false, url: nil, account_ids: [other_user.id]}
]
end
@@ -66,11 +104,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|> Object.update_data(%{"reactions" => %{"☕" => [user.ap_id], "x" => 1}})
activity = Activity.get_by_id(activity.id)
-
status = StatusView.render("show.json", activity: activity, for: user)
assert status[:pleroma][:emoji_reactions] == [
- %{name: "☕", count: 1, me: true}
+ %{name: "☕", count: 1, me: true, url: nil, account_ids: [user.id]}
]
end
@@ -90,7 +127,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
status = StatusView.render("show.json", activity: activity)
assert status[:pleroma][:emoji_reactions] == [
- %{name: "☕", count: 1, me: false}
+ %{name: "☕", count: 1, me: false, url: nil, account_ids: [other_user.id]}
]
status = StatusView.render("show.json", activity: activity, for: user)
@@ -102,19 +139,25 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
status = StatusView.render("show.json", activity: activity)
assert status[:pleroma][:emoji_reactions] == [
- %{name: "☕", count: 2, me: false}
+ %{
+ name: "☕",
+ count: 2,
+ me: false,
+ url: nil,
+ account_ids: [third_user.id, other_user.id]
+ }
]
status = StatusView.render("show.json", activity: activity, for: user)
assert status[:pleroma][:emoji_reactions] == [
- %{name: "☕", count: 1, me: false}
+ %{name: "☕", count: 1, me: false, url: nil, account_ids: [third_user.id]}
]
status = StatusView.render("show.json", activity: activity, for: other_user)
assert status[:pleroma][:emoji_reactions] == [
- %{name: "☕", count: 1, me: true}
+ %{name: "☕", count: 1, me: true, url: nil, account_ids: [other_user.id]}
]
end
@@ -283,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,
@@ -379,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/pleroma/web/metadata/providers/rel_me_test.exs b/test/pleroma/web/metadata/providers/rel_me_test.exs
index cce4f3607..793669037 100644
--- a/test/pleroma/web/metadata/providers/rel_me_test.exs
+++ b/test/pleroma/web/metadata/providers/rel_me_test.exs
@@ -11,11 +11,24 @@ defmodule Pleroma.Web.Metadata.Providers.RelMeTest do
bio =
~s(<a href="https://some-link.com">https://some-link.com</a> <a rel="me" href="https://another-link.com">https://another-link.com</a> <link href="http://some.com"> <link rel="me" href="http://some3.com">)
- user = insert(:user, %{bio: bio})
+ fields = [
+ %{
+ "name" => "profile",
+ "value" => ~S(<a rel="me" href="http://profile.com">http://profile.com</a>)
+ },
+ %{
+ "name" => "like",
+ "value" => ~S(<a href="http://cofe.io">http://cofe.io</a>)
+ },
+ %{"name" => "foo", "value" => "bar"}
+ ]
+
+ user = insert(:user, %{bio: bio, fields: fields})
assert RelMe.build_tags(%{user: user}) == [
{:link, [rel: "me", href: "http://some3.com"], []},
- {:link, [rel: "me", href: "https://another-link.com"], []}
+ {:link, [rel: "me", href: "https://another-link.com"], []},
+ {:link, [rel: "me", href: "http://profile.com"], []}
]
end
end
diff --git a/test/pleroma/web/metadata/providers/twitter_card_test.exs b/test/pleroma/web/metadata/providers/twitter_card_test.exs
index be4cfbe7b..f8d01c5c8 100644
--- a/test/pleroma/web/metadata/providers/twitter_card_test.exs
+++ b/test/pleroma/web/metadata/providers/twitter_card_test.exs
@@ -182,7 +182,8 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest do
{:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []},
{:meta, [name: "twitter:description", content: "pleroma in a nutshell"], []},
{:meta, [name: "twitter:card", content: "summary_large_image"], []},
- {:meta, [name: "twitter:player", content: "https://pleroma.gov/tenshi.png"], []},
+ {:meta, [name: "twitter:image", content: "https://pleroma.gov/tenshi.png"], []},
+ {:meta, [name: "twitter:image:alt", content: ""], []},
{:meta, [name: "twitter:player:width", content: "1280"], []},
{:meta, [name: "twitter:player:height", content: "1024"], []},
{:meta, [name: "twitter:card", content: "player"], []},
diff --git a/test/pleroma/web/pleroma_api/controllers/emoji_reaction_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/emoji_reaction_controller_test.exs
index 77c75b560..21e7d4839 100644
--- a/test/pleroma/web/pleroma_api/controllers/emoji_reaction_controller_test.exs
+++ b/test/pleroma/web/pleroma_api/controllers/emoji_reaction_controller_test.exs
@@ -17,23 +17,113 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionControllerTest do
user = insert(:user)
other_user = insert(:user)
+ note = insert(:note, user: user, data: %{"reactions" => [["👍", [other_user.ap_id], nil]]})
+ activity = insert(:note_activity, note: note, user: user)
+
+ result =
+ conn
+ |> assign(:user, other_user)
+ |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
+ |> put("/api/v1/pleroma/statuses/#{activity.id}/reactions/\u26A0")
+ |> json_response_and_validate_schema(200)
+
+ assert %{"id" => id} = result
+ assert to_string(activity.id) == id
+
+ assert result["pleroma"]["emoji_reactions"] == [
+ %{
+ "name" => "👍",
+ "count" => 1,
+ "me" => true,
+ "url" => nil,
+ "account_ids" => [other_user.id]
+ },
+ %{
+ "name" => "\u26A0\uFE0F",
+ "count" => 1,
+ "me" => true,
+ "url" => nil,
+ "account_ids" => [other_user.id]
+ }
+ ]
+
{:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
+ ObanHelpers.perform_all()
+
+ # Reacting with a custom emoji
result =
conn
|> assign(:user, other_user)
|> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
- |> put("/api/v1/pleroma/statuses/#{activity.id}/reactions/☕")
+ |> put("/api/v1/pleroma/statuses/#{activity.id}/reactions/:dinosaur:")
|> json_response_and_validate_schema(200)
- # We return the status, but this our implementation detail.
assert %{"id" => id} = result
assert to_string(activity.id) == id
assert result["pleroma"]["emoji_reactions"] == [
- %{"name" => "☕", "count" => 1, "me" => true}
+ %{
+ "name" => "dinosaur",
+ "count" => 1,
+ "me" => true,
+ "url" => "http://localhost:4001/emoji/dino walking.gif",
+ "account_ids" => [other_user.id]
+ }
+ ]
+
+ # Reacting with a remote emoji
+ note =
+ insert(:note,
+ user: user,
+ data: %{
+ "reactions" => [
+ ["👍", [other_user.ap_id], nil],
+ ["wow", [other_user.ap_id], "https://remote/emoji/wow"]
+ ]
+ }
+ )
+
+ activity = insert(:note_activity, note: note, user: user)
+
+ result =
+ conn
+ |> assign(:user, user)
+ |> assign(:token, insert(:oauth_token, user: user, scopes: ["write:statuses"]))
+ |> put("/api/v1/pleroma/statuses/#{activity.id}/reactions/:wow@remote:")
+ |> json_response(200)
+
+ assert result["pleroma"]["emoji_reactions"] == [
+ %{
+ "account_ids" => [other_user.id],
+ "count" => 1,
+ "me" => false,
+ "name" => "👍",
+ "url" => nil
+ },
+ %{
+ "name" => "wow@remote",
+ "count" => 2,
+ "me" => true,
+ "url" => "https://remote/emoji/wow",
+ "account_ids" => [user.id, other_user.id]
+ }
]
+ # Reacting with a remote custom emoji that hasn't been reacted with yet
+ note =
+ insert(:note,
+ user: user
+ )
+
+ activity = insert(:note_activity, note: note, user: user)
+
+ assert conn
+ |> assign(:user, user)
+ |> assign(:token, insert(:oauth_token, user: user, scopes: ["write:statuses"]))
+ |> put("/api/v1/pleroma/statuses/#{activity.id}/reactions/:wow@remote:")
+ |> json_response(400)
+
# Reacting with a non-emoji
assert conn
|> assign(:user, other_user)
@@ -46,8 +136,21 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionControllerTest do
user = insert(:user)
other_user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
+ note =
+ insert(:note,
+ user: user,
+ data: %{"reactions" => [["wow", [user.ap_id], "https://remote/emoji/wow"]]}
+ )
+
+ activity = insert(:note_activity, note: note, user: user)
+
+ ObanHelpers.perform_all()
+
{:ok, _reaction_activity} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
+ {:ok, _reaction_activity} = CommonAPI.react_with_emoji(activity.id, other_user, ":dinosaur:")
+
+ {:ok, _reaction_activity} =
+ CommonAPI.react_with_emoji(activity.id, other_user, ":wow@remote:")
ObanHelpers.perform_all()
@@ -60,11 +163,47 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionControllerTest do
assert %{"id" => id} = json_response_and_validate_schema(result, 200)
assert to_string(activity.id) == id
+ # Remove custom emoji
+
+ result =
+ conn
+ |> assign(:user, other_user)
+ |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
+ |> delete("/api/v1/pleroma/statuses/#{activity.id}/reactions/:dinosaur:")
+
+ assert %{"id" => id} = json_response_and_validate_schema(result, 200)
+ assert to_string(activity.id) == id
+
ObanHelpers.perform_all()
object = Object.get_by_ap_id(activity.data["object"])
- assert object.data["reaction_count"] == 0
+ assert object.data["reaction_count"] == 2
+
+ # Remove custom remote emoji
+ result =
+ conn
+ |> assign(:user, other_user)
+ |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
+ |> delete("/api/v1/pleroma/statuses/#{activity.id}/reactions/:wow@remote:")
+ |> json_response(200)
+
+ assert result["pleroma"]["emoji_reactions"] == [
+ %{
+ "name" => "wow@remote",
+ "count" => 1,
+ "me" => false,
+ "url" => "https://remote/emoji/wow",
+ "account_ids" => [user.id]
+ }
+ ]
+
+ # Remove custom remote emoji that hasn't been reacted with yet
+ assert conn
+ |> assign(:user, other_user)
+ |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
+ |> delete("/api/v1/pleroma/statuses/#{activity.id}/reactions/:zoop@remote:")
+ |> json_response(400)
end
test "GET /api/v1/pleroma/statuses/:id/reactions", %{conn: conn} do
@@ -106,6 +245,38 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionControllerTest do
result
end
+ test "GET /api/v1/pleroma/statuses/:id/reactions with legacy format", %{conn: conn} do
+ user = insert(:user)
+ other_user = insert(:user)
+
+ note =
+ insert(:note,
+ user: user,
+ data: %{
+ "reactions" => [["😿", [other_user.ap_id]]]
+ }
+ )
+
+ activity = insert(:note_activity, user: user, note: note)
+
+ result =
+ conn
+ |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
+ |> json_response_and_validate_schema(200)
+
+ other_user_id = other_user.id
+
+ assert [
+ %{
+ "name" => "😿",
+ "count" => 1,
+ "me" => false,
+ "url" => nil,
+ "accounts" => [%{"id" => ^other_user_id}]
+ }
+ ] = result
+ end
+
test "GET /api/v1/pleroma/statuses/:id/reactions?with_muted=true", %{conn: conn} do
user = insert(:user)
user2 = insert(:user)
@@ -181,7 +352,15 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionControllerTest do
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
- assert [%{"name" => "🎅", "count" => 1, "accounts" => [represented_user], "me" => false}] =
+ assert [
+ %{
+ "name" => "🎅",
+ "count" => 1,
+ "accounts" => [represented_user],
+ "me" => false,
+ "url" => nil
+ }
+ ] =
conn
|> get("/api/v1/pleroma/statuses/#{activity.id}/reactions/🎅")
|> json_response_and_validate_schema(200)
diff --git a/test/pleroma/web/pleroma_api/views/backup_view_test.exs b/test/pleroma/web/pleroma_api/views/backup_view_test.exs
index a86688bc4..6908463d6 100644
--- a/test/pleroma/web/pleroma_api/views/backup_view_test.exs
+++ b/test/pleroma/web/pleroma_api/views/backup_view_test.exs
@@ -15,4 +15,43 @@ defmodule Pleroma.Web.PleromaAPI.BackupViewTest do
result = BackupView.render("show.json", backup: backup)
assert result.id == backup.id
end
+
+ test "it renders the state and processed_number" do
+ user = insert(:user)
+ backup = Backup.new(user)
+
+ result = BackupView.render("show.json", backup: backup)
+ assert result.state == to_string(backup.state)
+ assert result.processed_number == backup.processed_number
+ end
+
+ test "it renders failed state with legacy records" do
+ backup = %Backup{
+ id: 0,
+ content_type: "application/zip",
+ file_name: "dummy",
+ file_size: 1,
+ state: :invalid,
+ processed: true,
+ processed_number: 1,
+ inserted_at: NaiveDateTime.utc_now()
+ }
+
+ result = BackupView.render("show.json", backup: backup)
+ assert result.state == "complete"
+
+ backup = %Backup{
+ id: 0,
+ content_type: "application/zip",
+ file_name: "dummy",
+ file_size: 1,
+ state: :invalid,
+ processed: false,
+ processed_number: 1,
+ inserted_at: NaiveDateTime.utc_now()
+ }
+
+ result = BackupView.render("show.json", backup: backup)
+ assert result.state == "failed"
+ end
end
diff --git a/test/pleroma/web/plugs/uploaded_media_plug_test.exs b/test/pleroma/web/plugs/uploaded_media_plug_test.exs
index ec46b0537..8323ff6ab 100644
--- a/test/pleroma/web/plugs/uploaded_media_plug_test.exs
+++ b/test/pleroma/web/plugs/uploaded_media_plug_test.exs
@@ -33,11 +33,11 @@ defmodule Pleroma.Web.Plugs.UploadedMediaPlugTest do
test "sends Content-Disposition header when name param is set", %{
attachment_url: attachment_url
} do
- conn = get(build_conn(), attachment_url <> "?name=\"cofe\".gif")
+ conn = get(build_conn(), attachment_url <> ~s[?name="cofe".gif])
assert Enum.any?(
conn.resp_headers,
- &(&1 == {"content-disposition", "filename=\"\\\"cofe\\\".gif\""})
+ &(&1 == {"content-disposition", ~s[inline; filename="\\"cofe\\".gif"]})
)
end
end
diff --git a/test/pleroma/web/streamer_test.exs b/test/pleroma/web/streamer_test.exs
index 7ab0e379b..d85358fd4 100644
--- a/test/pleroma/web/streamer_test.exs
+++ b/test/pleroma/web/streamer_test.exs
@@ -22,6 +22,10 @@ defmodule Pleroma.Web.StreamerTest do
setup do: clear_config([:instance, :skip_thread_containment])
describe "get_topic/_ (unauthenticated)" do
+ test "allows no stream" do
+ assert {:ok, nil} = Streamer.get_topic(nil, nil, nil)
+ end
+
test "allows public" do
assert {:ok, "public"} = Streamer.get_topic("public", nil, nil)
assert {:ok, "public:local"} = Streamer.get_topic("public:local", nil, nil)
@@ -242,7 +246,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user", user, oauth_token)
{:ok, activity} = CommonAPI.post(user, %{status: "hey"})
- assert_receive {:render_with_user, _, _, ^activity}
+ assert_receive {:render_with_user, _, _, ^activity, _}
refute Streamer.filtered_by_user?(user, activity)
end
@@ -253,7 +257,7 @@ defmodule Pleroma.Web.StreamerTest do
{:ok, activity} = CommonAPI.post(other_user, %{status: "hey"})
{:ok, announce} = CommonAPI.repeat(activity.id, user)
- assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce}
+ assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce, _}
refute Streamer.filtered_by_user?(user, announce)
end
@@ -306,7 +310,7 @@ defmodule Pleroma.Web.StreamerTest do
{:ok, %Pleroma.Activity{data: _data, local: false} = announce} =
Pleroma.Web.ActivityPub.Transmogrifier.handle_incoming(data)
- assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce}
+ assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce, _}
refute Streamer.filtered_by_user?(user, announce)
end
@@ -318,7 +322,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user", user, oauth_token)
Streamer.stream("user", notify)
- assert_receive {:render_with_user, _, _, ^notify}
+ assert_receive {:render_with_user, _, _, ^notify, _}
refute Streamer.filtered_by_user?(user, notify)
end
@@ -330,7 +334,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
Streamer.stream("user:notification", notify)
- assert_receive {:render_with_user, _, _, ^notify}
+ assert_receive {:render_with_user, _, _, ^notify, _}
refute Streamer.filtered_by_user?(user, notify)
end
@@ -351,7 +355,12 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user:pleroma_chat", user, oauth_token)
Streamer.stream("user:pleroma_chat", {user, cm_ref})
- text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref})
+ text =
+ StreamerView.render(
+ "chat_update.json",
+ %{chat_message_reference: cm_ref},
+ "user:pleroma_chat:#{user.id}"
+ )
assert text =~ "hey cirno"
assert_receive {:text, ^text}
@@ -369,7 +378,12 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user", user, oauth_token)
Streamer.stream("user", {user, cm_ref})
- text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref})
+ text =
+ StreamerView.render(
+ "chat_update.json",
+ %{chat_message_reference: cm_ref},
+ "user:#{user.id}"
+ )
assert text =~ "hey cirno"
assert_receive {:text, ^text}
@@ -390,7 +404,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
Streamer.stream("user:notification", notify)
- assert_receive {:render_with_user, _, _, ^notify}
+ assert_receive {:render_with_user, _, _, ^notify, _}
refute Streamer.filtered_by_user?(user, notify)
end
@@ -436,7 +450,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
{:ok, favorite_activity} = CommonAPI.favorite(user2, activity.id)
- assert_receive {:render_with_user, _, "notification.json", notif}
+ assert_receive {:render_with_user, _, "notification.json", notif, _}
assert notif.activity.id == favorite_activity.id
refute Streamer.filtered_by_user?(user, notif)
end
@@ -465,7 +479,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
{:ok, _follower, _followed, follow_activity} = CommonAPI.follow(user2, user)
- assert_receive {:render_with_user, _, "notification.json", notif}
+ assert_receive {:render_with_user, _, "notification.json", notif, _}
assert notif.activity.id == follow_activity.id
refute Streamer.filtered_by_user?(user, notif)
end
@@ -530,7 +544,7 @@ defmodule Pleroma.Web.StreamerTest do
{:ok, edited} = CommonAPI.update(sender, activity, %{status: "mew mew"})
create = Pleroma.Activity.get_create_by_object_ap_id_with_object(activity.object.data["id"])
- assert_receive {:render_with_user, _, "status_update.json", ^create}
+ assert_receive {:render_with_user, _, "status_update.json", ^create, _}
refute Streamer.filtered_by_user?(user, edited)
end
@@ -541,7 +555,7 @@ defmodule Pleroma.Web.StreamerTest do
{:ok, edited} = CommonAPI.update(user, activity, %{status: "mew mew"})
create = Pleroma.Activity.get_create_by_object_ap_id_with_object(activity.object.data["id"])
- assert_receive {:render_with_user, _, "status_update.json", ^create}
+ assert_receive {:render_with_user, _, "status_update.json", ^create, _}
refute Streamer.filtered_by_user?(user, edited)
end
end
@@ -554,7 +568,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("public", user, oauth_token)
{:ok, activity} = CommonAPI.post(other_user, %{status: "Test"})
- assert_receive {:render_with_user, _, _, ^activity}
+ assert_receive {:render_with_user, _, _, ^activity, _}
refute Streamer.filtered_by_user?(other_user, activity)
end
@@ -654,7 +668,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("public", user, oauth_token)
Streamer.stream("public", activity)
- assert_receive {:render_with_user, _, _, ^activity}
+ assert_receive {:render_with_user, _, _, ^activity, _}
assert Streamer.filtered_by_user?(user, activity)
end
@@ -676,7 +690,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("public", user, oauth_token)
Streamer.stream("public", activity)
- assert_receive {:render_with_user, _, _, ^activity}
+ assert_receive {:render_with_user, _, _, ^activity, _}
refute Streamer.filtered_by_user?(user, activity)
end
@@ -699,7 +713,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("public", user, oauth_token)
Streamer.stream("public", activity)
- assert_receive {:render_with_user, _, _, ^activity}
+ assert_receive {:render_with_user, _, _, ^activity, _}
refute Streamer.filtered_by_user?(user, activity)
end
end
@@ -713,7 +727,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("public", user, oauth_token)
{:ok, activity} = CommonAPI.post(blocked_user, %{status: "Test"})
- assert_receive {:render_with_user, _, _, ^activity}
+ assert_receive {:render_with_user, _, _, ^activity, _}
assert Streamer.filtered_by_user?(user, activity)
end
@@ -730,17 +744,17 @@ defmodule Pleroma.Web.StreamerTest do
{:ok, activity_one} = CommonAPI.post(friend, %{status: "hey! @#{blockee.nickname}"})
- assert_receive {:render_with_user, _, _, ^activity_one}
+ assert_receive {:render_with_user, _, _, ^activity_one, _}
assert Streamer.filtered_by_user?(blocker, activity_one)
{:ok, activity_two} = CommonAPI.post(blockee, %{status: "hey! @#{friend.nickname}"})
- assert_receive {:render_with_user, _, _, ^activity_two}
+ assert_receive {:render_with_user, _, _, ^activity_two, _}
assert Streamer.filtered_by_user?(blocker, activity_two)
{:ok, activity_three} = CommonAPI.post(blockee, %{status: "hey! @#{blocker.nickname}"})
- assert_receive {:render_with_user, _, _, ^activity_three}
+ assert_receive {:render_with_user, _, _, ^activity_three, _}
assert Streamer.filtered_by_user?(blocker, activity_three)
end
end
@@ -801,7 +815,7 @@ defmodule Pleroma.Web.StreamerTest do
visibility: "private"
})
- assert_receive {:render_with_user, _, _, ^activity}
+ assert_receive {:render_with_user, _, _, ^activity, _}
refute Streamer.filtered_by_user?(user_a, activity)
end
end
@@ -819,7 +833,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user", user1, user1_token)
{:ok, announce_activity} = CommonAPI.repeat(create_activity.id, user2)
- assert_receive {:render_with_user, _, _, ^announce_activity}
+ assert_receive {:render_with_user, _, _, ^announce_activity, _}
assert Streamer.filtered_by_user?(user1, announce_activity)
end
@@ -835,7 +849,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user", user1, user1_token)
{:ok, _announce_activity} = CommonAPI.repeat(create_activity.id, user2)
- assert_receive {:render_with_user, _, "notification.json", notif}
+ assert_receive {:render_with_user, _, "notification.json", notif, _}
assert Streamer.filtered_by_user?(user1, notif)
end
@@ -851,7 +865,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user", user1, user1_token)
{:ok, _favorite_activity} = CommonAPI.favorite(user2, create_activity.id)
- assert_receive {:render_with_user, _, "notification.json", notif}
+ assert_receive {:render_with_user, _, "notification.json", notif, _}
refute Streamer.filtered_by_user?(user1, notif)
end
end
@@ -866,7 +880,7 @@ defmodule Pleroma.Web.StreamerTest do
{:ok, activity} = CommonAPI.post(user, %{status: "super hot take"})
{:ok, _} = CommonAPI.add_mute(user2, activity)
- assert_receive {:render_with_user, _, _, ^activity}
+ assert_receive {:render_with_user, _, _, ^activity, _}
assert Streamer.filtered_by_user?(user2, activity)
end
end
@@ -908,7 +922,7 @@ defmodule Pleroma.Web.StreamerTest do
})
create_activity_id = create_activity.id
- assert_receive {:render_with_user, _, _, ^create_activity}
+ assert_receive {:render_with_user, _, _, ^create_activity, _}
assert_receive {:text, received_conversation1}
assert %{"event" => "conversation", "payload" => _} = Jason.decode!(received_conversation1)
@@ -943,8 +957,8 @@ defmodule Pleroma.Web.StreamerTest do
visibility: "direct"
})
- assert_receive {:render_with_user, _, _, ^create_activity}
- assert_receive {:render_with_user, _, _, ^create_activity2}
+ assert_receive {:render_with_user, _, _, ^create_activity, _}
+ assert_receive {:render_with_user, _, _, ^create_activity2, _}
assert_receive {:text, received_conversation1}
assert %{"event" => "conversation", "payload" => _} = Jason.decode!(received_conversation1)
assert_receive {:text, received_conversation1}
@@ -973,7 +987,7 @@ defmodule Pleroma.Web.StreamerTest do
receive do
{StreamerTest, :ready} ->
- assert_receive {:render_with_user, _, "update.json", _}
+ assert_receive {:render_with_user, _, "update.json", _, _}
receive do
{StreamerTest, :revoked} -> finalize.()
diff --git a/test/pleroma/web/xml_test.exs b/test/pleroma/web/xml_test.exs
index 89d4709b6..49306430b 100644
--- a/test/pleroma/web/xml_test.exs
+++ b/test/pleroma/web/xml_test.exs
@@ -3,6 +3,11 @@ defmodule Pleroma.Web.XMLTest do
alias Pleroma.Web.XML
+ test "refuses to parse any entities from XML" do
+ data = File.read!("test/fixtures/xml_billion_laughs.xml")
+ assert(:error == XML.parse_document(data))
+ end
+
test "refuses to load external entities from XML" do
data = File.read!("test/fixtures/xml_external_entities.xml")
assert(:error == XML.parse_document(data))
diff --git a/test/support/factory.ex b/test/support/factory.ex
index 09f02458c..d94544717 100644
--- a/test/support/factory.ex
+++ b/test/support/factory.ex
@@ -50,7 +50,6 @@ defmodule Pleroma.Factory do
last_refreshed_at: NaiveDateTime.utc_now(),
notification_settings: %Pleroma.User.NotificationSetting{},
multi_factor_authentication_settings: %Pleroma.MFA.Settings{},
- ap_enabled: true,
keys: pem
}
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)}"}
diff --git a/test/test_helper.exs b/test/test_helper.exs
index 60a61484f..7727cffbc 100644
--- a/test/test_helper.exs
+++ b/test/test_helper.exs
@@ -2,6 +2,8 @@
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
+Code.put_compiler_option(:warnings_as_errors, true)
+
os_exclude = if :os.type() == {:unix, :darwin}, do: [skip_on_mac: true], else: []
ExUnit.start(exclude: [:federated, :erratic] ++ os_exclude)