Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into pleroma-meilisearch
This commit is contained in:
commit
0c5cc51983
746 changed files with 11830 additions and 5643 deletions
28
test/fixtures/custom-emoji-reaction.json
vendored
Normal file
28
test/fixtures/custom-emoji-reaction.json
vendored
Normal file
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
31
test/fixtures/fep-e232.json
vendored
Normal file
31
test/fixtures/fep-e232.json
vendored
Normal file
|
|
@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
1
test/fixtures/hubzilla-actor.json
vendored
Normal file
1
test/fixtures/hubzilla-actor.json
vendored
Normal file
|
|
@ -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="}}
|
||||
1
test/fixtures/hubzilla-create-image.json
vendored
Normal file
1
test/fixtures/hubzilla-create-image.json
vendored
Normal file
|
|
@ -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="}}
|
||||
BIN
test/fixtures/image_with_imagedescription_and_caption-abstract_and_stray_data_after.png
vendored
Normal file
BIN
test/fixtures/image_with_imagedescription_and_caption-abstract_and_stray_data_after.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 820 B |
BIN
test/fixtures/image_with_stray_data_after.png
vendored
Executable file
BIN
test/fixtures/image_with_stray_data_after.png
vendored
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 102 KiB |
1
test/fixtures/mastodon-nodeinfo20.json
vendored
Normal file
1
test/fixtures/mastodon-nodeinfo20.json
vendored
Normal file
|
|
@ -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":{}}
|
||||
1
test/fixtures/mastodon-well-known-nodeinfo.json
vendored
Normal file
1
test/fixtures/mastodon-well-known-nodeinfo.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"links":[{"rel":"http://nodeinfo.diaspora.software/ns/schema/2.0","href":"https://mastodon.example.org/nodeinfo/2.0"}]}
|
||||
54
test/fixtures/quote_post/fedibird_quote_mismatched.json
vendored
Normal file
54
test/fixtures/quote_post/fedibird_quote_mismatched.json
vendored
Normal file
|
|
@ -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": []
|
||||
}
|
||||
}
|
||||
}
|
||||
52
test/fixtures/quote_post/fedibird_quote_post.json
vendored
Normal file
52
test/fixtures/quote_post/fedibird_quote_post.json
vendored
Normal file
|
|
@ -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": []
|
||||
}
|
||||
}
|
||||
}
|
||||
54
test/fixtures/quote_post/fedibird_quote_uri.json
vendored
Normal file
54
test/fixtures/quote_post/fedibird_quote_uri.json
vendored
Normal file
|
|
@ -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": []
|
||||
}
|
||||
}
|
||||
}
|
||||
17
test/fixtures/quote_post/fep-e232-tag-example.json
vendored
Normal file
17
test/fixtures/quote_post/fep-e232-tag-example.json
vendored
Normal file
|
|
@ -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"
|
||||
}
|
||||
46
test/fixtures/quote_post/misskey_quote_post.json
vendored
Normal file
46
test/fixtures/quote_post/misskey_quote_post.json
vendored
Normal file
|
|
@ -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": []
|
||||
}
|
||||
64
test/fixtures/tesla_mock/aimu@misskey.io.json
vendored
Normal file
64
test/fixtures/tesla_mock/aimu@misskey.io.json
vendored
Normal file
|
|
@ -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"
|
||||
}
|
||||
44
test/fixtures/tesla_mock/misskey.io_8vs6wxufd0.json
vendored
Normal file
44
test/fixtures/tesla_mock/misskey.io_8vs6wxufd0.json
vendored
Normal file
|
|
@ -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": []
|
||||
}
|
||||
1
test/fixtures/wildebeest-nodeinfo21.json
vendored
Normal file
1
test/fixtures/wildebeest-nodeinfo21.json
vendored
Normal file
|
|
@ -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"}}}
|
||||
1
test/fixtures/wildebeest-well-known-nodeinfo.json
vendored
Normal file
1
test/fixtures/wildebeest-well-known-nodeinfo.json
vendored
Normal file
|
|
@ -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"}]}
|
||||
15
test/fixtures/xml_billion_laughs.xml
vendored
Normal file
15
test/fixtures/xml_billion_laughs.xml
vendored
Normal file
|
|
@ -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>
|
||||
3
test/fixtures/xml_external_entities.xml
vendored
Normal file
3
test/fixtures/xml_external_entities.xml
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
|
||||
<stockCheck><productId>&xxe;</productId></stockCheck>
|
||||
62
test/mix/tasks/pleroma/openapi_spec_test.exs
Normal file
62
test/mix/tasks/pleroma/openapi_spec_test.exs
Normal file
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -10,13 +10,15 @@ 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"
|
||||
end
|
||||
|
||||
test "merged runtime config" do
|
||||
assert :ok == File.chmod!("test/fixtures/config/temp.secret.exs", 0o640)
|
||||
|
||||
merged =
|
||||
ReleaseRuntimeProvider.load([], config_path: "test/fixtures/config/temp.secret.exs")
|
||||
|
||||
|
|
@ -25,6 +27,8 @@ defmodule Pleroma.Config.ReleaseRuntimeProviderTest do
|
|||
end
|
||||
|
||||
test "merged exported config" do
|
||||
assert :ok == File.chmod!("test/fixtures/config/temp.exported_from_db.secret.exs", 0o640)
|
||||
|
||||
ExUnit.CaptureIO.capture_io(fn ->
|
||||
merged =
|
||||
ReleaseRuntimeProvider.load([],
|
||||
|
|
@ -37,6 +41,9 @@ defmodule Pleroma.Config.ReleaseRuntimeProviderTest do
|
|||
end
|
||||
|
||||
test "runtime config is merged with exported config" do
|
||||
assert :ok == File.chmod!("test/fixtures/config/temp.secret.exs", 0o640)
|
||||
assert :ok == File.chmod!("test/fixtures/config/temp.exported_from_db.secret.exs", 0o640)
|
||||
|
||||
merged =
|
||||
ReleaseRuntimeProvider.load([],
|
||||
config_path: "test/fixtures/config/temp.secret.exs",
|
||||
|
|
|
|||
|
|
@ -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 == BareUri.cast(1)
|
||||
assert :error == BareUri.cast("foo")
|
||||
assert :error == BareUri.cast("foo bar")
|
||||
end
|
||||
end
|
||||
|
|
@ -90,4 +90,8 @@ defmodule Pleroma.Emoji.PackTest do
|
|||
|
||||
assert updated_pack.files_count == 1
|
||||
end
|
||||
|
||||
test "load_pack/1 ignores path traversal in a forged pack name", %{pack: pack} do
|
||||
assert {:ok, ^pack} = Pack.load_pack("../../../../../dump_pack")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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 = [
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.NotificationTest do
|
||||
use Pleroma.DataCase
|
||||
use Pleroma.DataCase, async: false
|
||||
|
||||
import Pleroma.Factory
|
||||
import Mock
|
||||
|
|
@ -32,20 +32,26 @@ defmodule Pleroma.NotificationTest do
|
|||
refute {:ok, [nil]} == Notification.create_notifications(activity)
|
||||
end
|
||||
|
||||
test "creates a notification for a report" do
|
||||
test "creates a report notification only for privileged users" do
|
||||
reporting_user = insert(:user)
|
||||
reported_user = insert(:user)
|
||||
{:ok, moderator_user} = insert(:user) |> User.admin_api_update(%{is_moderator: true})
|
||||
moderator_user = insert(:user, is_moderator: true)
|
||||
|
||||
{:ok, activity} = CommonAPI.report(reporting_user, %{account_id: reported_user.id})
|
||||
clear_config([:instance, :moderator_privileges], [])
|
||||
{:ok, activity1} = CommonAPI.report(reporting_user, %{account_id: reported_user.id})
|
||||
{:ok, []} = Notification.create_notifications(activity1)
|
||||
|
||||
{:ok, [notification]} = Notification.create_notifications(activity)
|
||||
clear_config([:instance, :moderator_privileges], [:reports_manage_reports])
|
||||
{:ok, activity2} = CommonAPI.report(reporting_user, %{account_id: reported_user.id})
|
||||
{:ok, [notification]} = Notification.create_notifications(activity2)
|
||||
|
||||
assert notification.user_id == moderator_user.id
|
||||
assert notification.type == "pleroma:report"
|
||||
end
|
||||
|
||||
test "suppresses notification to reporter if reporter is an admin" do
|
||||
test "suppresses notifications for own reports" do
|
||||
clear_config([:instance, :admin_privileges], [:reports_manage_reports])
|
||||
|
||||
reporting_admin = insert(:user, is_admin: true)
|
||||
reported_user = insert(:user)
|
||||
other_admin = insert(:user, is_admin: true)
|
||||
|
|
@ -246,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 =
|
||||
|
|
@ -254,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)
|
||||
|
|
@ -328,6 +334,32 @@ defmodule Pleroma.NotificationTest do
|
|||
refute Notification.create_notification(activity, followed)
|
||||
end
|
||||
|
||||
test "it disables notifications from non-followees" do
|
||||
follower = insert(:user)
|
||||
|
||||
followed =
|
||||
insert(:user,
|
||||
notification_settings: %Pleroma.User.NotificationSetting{block_from_strangers: true}
|
||||
)
|
||||
|
||||
CommonAPI.follow(follower, followed)
|
||||
{:ok, activity} = CommonAPI.post(follower, %{status: "hey @#{followed.nickname}"})
|
||||
refute Notification.create_notification(activity, followed)
|
||||
end
|
||||
|
||||
test "it allows notifications from followees" do
|
||||
poster = insert(:user)
|
||||
|
||||
receiver =
|
||||
insert(:user,
|
||||
notification_settings: %Pleroma.User.NotificationSetting{block_from_strangers: true}
|
||||
)
|
||||
|
||||
CommonAPI.follow(receiver, poster)
|
||||
{:ok, activity} = CommonAPI.post(poster, %{status: "hey @#{receiver.nickname}"})
|
||||
assert Notification.create_notification(activity, receiver)
|
||||
end
|
||||
|
||||
test "it doesn't create a notification for user if he is the activity author" do
|
||||
activity = insert(:note_activity)
|
||||
author = User.get_cached_by_ap_id(activity.data["actor"])
|
||||
|
|
@ -542,25 +574,6 @@ defmodule Pleroma.NotificationTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "destroy_multiple_from_types/2" do
|
||||
test "clears all notifications of a certain type for a given user" do
|
||||
report_activity = insert(:report_activity)
|
||||
user1 = insert(:user, is_moderator: true, is_admin: true)
|
||||
user2 = insert(:user, is_moderator: true, is_admin: true)
|
||||
{:ok, _} = Notification.create_notifications(report_activity)
|
||||
|
||||
{:ok, _} =
|
||||
CommonAPI.post(user2, %{
|
||||
status: "hey @#{user1.nickname} !"
|
||||
})
|
||||
|
||||
Notification.destroy_multiple_from_types(user1, ["pleroma:report"])
|
||||
|
||||
assert [%Pleroma.Notification{type: "mention"}] = Notification.for_user(user1)
|
||||
assert [%Pleroma.Notification{type: "pleroma:report"}] = Notification.for_user(user2)
|
||||
end
|
||||
end
|
||||
|
||||
describe "set_read_up_to()" do
|
||||
test "it sets all notifications as read up to a specified notification ID" do
|
||||
user = insert(:user)
|
||||
|
|
@ -1238,5 +1251,32 @@ defmodule Pleroma.NotificationTest do
|
|||
|
||||
assert length(Notification.for_user(user)) == 1
|
||||
end
|
||||
|
||||
test "it returns notifications when related object is without content and filters are defined",
|
||||
%{user: user} do
|
||||
followed_user = insert(:user, is_locked: true)
|
||||
|
||||
insert(:filter, user: followed_user, phrase: "test", hide: true)
|
||||
|
||||
{:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
|
||||
refute FollowingRelationship.following?(user, followed_user)
|
||||
assert [notification] = Notification.for_user(followed_user)
|
||||
|
||||
assert %{type: "follow_request"} =
|
||||
NotificationView.render("show.json", %{
|
||||
notification: notification,
|
||||
for: followed_user
|
||||
})
|
||||
|
||||
assert {:ok, _} = CommonAPI.accept_follow_request(user, followed_user)
|
||||
|
||||
assert [notification] = Notification.for_user(followed_user)
|
||||
|
||||
assert %{type: "follow"} =
|
||||
NotificationView.render("show.json", %{
|
||||
notification: notification,
|
||||
for: followed_user
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,8 +9,12 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
alias Pleroma.Instances
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Object.Fetcher
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidator
|
||||
|
||||
require Pleroma.Constants
|
||||
|
||||
import Mock
|
||||
import Pleroma.Factory
|
||||
import Tesla.Mock
|
||||
|
||||
setup do
|
||||
|
|
@ -284,6 +288,8 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
|
||||
describe "refetching" do
|
||||
setup do
|
||||
insert(:user, ap_id: "https://mastodon.social/users/emelie")
|
||||
|
||||
object1 = %{
|
||||
"id" => "https://mastodon.social/1",
|
||||
"actor" => "https://mastodon.social/users/emelie",
|
||||
|
|
@ -293,10 +299,14 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
"bcc" => [],
|
||||
"bto" => [],
|
||||
"cc" => [],
|
||||
"to" => [],
|
||||
"summary" => ""
|
||||
"to" => [Pleroma.Constants.as_public()],
|
||||
"summary" => "",
|
||||
"published" => "2023-05-08 23:43:20Z",
|
||||
"updated" => "2023-05-09 23:43:20Z"
|
||||
}
|
||||
|
||||
{:ok, local_object1, _} = ObjectValidator.validate(object1, [])
|
||||
|
||||
object2 = %{
|
||||
"id" => "https://mastodon.social/2",
|
||||
"actor" => "https://mastodon.social/users/emelie",
|
||||
|
|
@ -306,8 +316,10 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
"bcc" => [],
|
||||
"bto" => [],
|
||||
"cc" => [],
|
||||
"to" => [],
|
||||
"to" => [Pleroma.Constants.as_public()],
|
||||
"summary" => "",
|
||||
"published" => "2023-05-08 23:43:20Z",
|
||||
"updated" => "2023-05-09 23:43:25Z",
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
|
|
@ -319,14 +331,18 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
"bcc" => [],
|
||||
"bto" => [],
|
||||
"cc" => [],
|
||||
"to" => [],
|
||||
"summary" => ""
|
||||
"to" => [Pleroma.Constants.as_public()],
|
||||
"summary" => "",
|
||||
"published" => "2023-05-08 23:43:20Z",
|
||||
"updated" => "2023-05-09 23:43:21Z"
|
||||
}
|
||||
],
|
||||
"totalItems" => 1
|
||||
}
|
||||
}
|
||||
|
||||
{:ok, local_object2, _} = ObjectValidator.validate(object2, [])
|
||||
|
||||
mock(fn
|
||||
%{
|
||||
method: :get,
|
||||
|
|
@ -335,7 +351,7 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
%Tesla.Env{
|
||||
status: 200,
|
||||
headers: [{"content-type", "application/activity+json"}],
|
||||
body: Jason.encode!(object1)
|
||||
body: Jason.encode!(object1 |> Map.put("updated", "2023-05-09 23:44:20Z"))
|
||||
}
|
||||
|
||||
%{
|
||||
|
|
@ -345,7 +361,7 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
%Tesla.Env{
|
||||
status: 200,
|
||||
headers: [{"content-type", "application/activity+json"}],
|
||||
body: Jason.encode!(object2)
|
||||
body: Jason.encode!(object2 |> Map.put("updated", "2023-05-09 23:44:20Z"))
|
||||
}
|
||||
|
||||
%{
|
||||
|
|
@ -370,7 +386,7 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
apply(HttpRequestMock, :request, [env])
|
||||
end)
|
||||
|
||||
%{object1: object1, object2: object2}
|
||||
%{object1: local_object1, object2: local_object2}
|
||||
end
|
||||
|
||||
test "it keeps formerRepresentations if remote does not have this attr", %{object1: object1} do
|
||||
|
|
@ -388,8 +404,9 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
"bcc" => [],
|
||||
"bto" => [],
|
||||
"cc" => [],
|
||||
"to" => [],
|
||||
"summary" => ""
|
||||
"to" => [Pleroma.Constants.as_public()],
|
||||
"summary" => "",
|
||||
"published" => "2023-05-08 23:43:20Z"
|
||||
}
|
||||
],
|
||||
"totalItems" => 1
|
||||
|
|
@ -467,6 +484,53 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
}
|
||||
} = refetched.data
|
||||
end
|
||||
|
||||
test "it keeps the history intact if only updated time has changed",
|
||||
%{object1: object1} do
|
||||
full_object1 =
|
||||
object1
|
||||
|> Map.merge(%{
|
||||
"updated" => "2023-05-08 23:43:47Z",
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
%{"type" => "Note", "content" => "mew mew 1"}
|
||||
],
|
||||
"totalItems" => 1
|
||||
}
|
||||
})
|
||||
|
||||
{:ok, o} = Object.create(full_object1)
|
||||
|
||||
assert {:ok, refetched} = Fetcher.refetch_object(o)
|
||||
|
||||
assert %{
|
||||
"content" => "test 1",
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [
|
||||
%{"content" => "mew mew 1"}
|
||||
],
|
||||
"totalItems" => 1
|
||||
}
|
||||
} = refetched.data
|
||||
end
|
||||
|
||||
test "it goes through ObjectValidator and MRF", %{object2: object2} do
|
||||
with_mock Pleroma.Web.ActivityPub.MRF, [:passthrough],
|
||||
filter: fn
|
||||
%{"type" => "Note"} = object ->
|
||||
{:ok, Map.put(object, "content", "MRFd content")}
|
||||
|
||||
arg ->
|
||||
passthrough([arg])
|
||||
end do
|
||||
{:ok, o} = Object.create(object2)
|
||||
|
||||
assert {:ok, refetched} = Fetcher.refetch_object(o)
|
||||
|
||||
assert %{"content" => "MRFd content"} = refetched.data
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "fetch with history" do
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -42,6 +42,33 @@ defmodule Pleroma.Upload.Filter.Exiftool.ReadDescriptionTest do
|
|||
{:ok, :filtered, uploads_after}
|
||||
end
|
||||
|
||||
test "Ignores warnings" do
|
||||
uploads = %Pleroma.Upload{
|
||||
name: "image_with_imagedescription_and_caption-abstract_and_stray_data_after.png",
|
||||
content_type: "image/png",
|
||||
path:
|
||||
Path.absname(
|
||||
"test/fixtures/image_with_imagedescription_and_caption-abstract_and_stray_data_after.png"
|
||||
),
|
||||
tempfile:
|
||||
Path.absname(
|
||||
"test/fixtures/image_with_imagedescription_and_caption-abstract_and_stray_data_after.png"
|
||||
)
|
||||
}
|
||||
|
||||
assert {:ok, :filtered, %{description: "a descriptive white pixel"}} =
|
||||
Filter.Exiftool.ReadDescription.filter(uploads)
|
||||
|
||||
uploads = %Pleroma.Upload{
|
||||
name: "image_with_stray_data_after.png",
|
||||
content_type: "image/png",
|
||||
path: Path.absname("test/fixtures/image_with_stray_data_after.png"),
|
||||
tempfile: Path.absname("test/fixtures/image_with_stray_data_after.png")
|
||||
}
|
||||
|
||||
assert {:ok, :filtered, %{description: nil}} = Filter.Exiftool.ReadDescription.filter(uploads)
|
||||
end
|
||||
|
||||
test "otherwise returns iptc:Caption-Abstract when present" do
|
||||
upload = %Pleroma.Upload{
|
||||
name: "image_with_caption-abstract.jpg",
|
||||
|
|
|
|||
|
|
@ -31,12 +31,19 @@ defmodule Pleroma.Upload.Filter.Exiftool.StripLocationTest do
|
|||
refute String.match?(exif_filtered, ~r/GPS/)
|
||||
end
|
||||
|
||||
test "verify webp files are skipped" do
|
||||
upload = %Pleroma.Upload{
|
||||
name: "sample.webp",
|
||||
content_type: "image/webp"
|
||||
}
|
||||
test "verify webp, heic, svg files are skipped" do
|
||||
uploads =
|
||||
~w{webp heic svg svg+xml}
|
||||
|> Enum.map(fn type ->
|
||||
%Pleroma.Upload{
|
||||
name: "sample.#{type}",
|
||||
content_type: "image/#{type}"
|
||||
}
|
||||
end)
|
||||
|
||||
assert Filter.Exiftool.StripLocation.filter(upload) == {:ok, :noop}
|
||||
uploads
|
||||
|> Enum.each(fn upload ->
|
||||
assert Filter.Exiftool.StripLocation.filter(upload) == {:ok, :noop}
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
32
test/pleroma/upload/filter/only_media_test.exs
Normal file
32
test/pleroma/upload/filter/only_media_test.exs
Normal file
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.User.QueryTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
use Pleroma.DataCase, async: false
|
||||
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.User
|
||||
|
|
@ -44,4 +44,63 @@ defmodule Pleroma.User.QueryTest do
|
|||
|> User.Query.build()
|
||||
|> Repo.all()
|
||||
end
|
||||
|
||||
describe "is_privileged param" do
|
||||
setup do
|
||||
%{
|
||||
user: insert(:user, local: true, is_admin: false, is_moderator: false),
|
||||
moderator_user: insert(:user, local: true, is_admin: false, is_moderator: true),
|
||||
admin_user: insert(:user, local: true, is_admin: true, is_moderator: false),
|
||||
admin_moderator_user: insert(:user, local: true, is_admin: true, is_moderator: true),
|
||||
remote_user: insert(:user, local: false, is_admin: true, is_moderator: true),
|
||||
non_active_user:
|
||||
insert(:user, local: true, is_admin: true, is_moderator: true, is_active: false)
|
||||
}
|
||||
end
|
||||
|
||||
test "doesn't return any users when there are no privileged roles" do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
clear_config([:instance, :moderator_privileges], [])
|
||||
|
||||
assert [] = User.Query.build(%{is_privileged: :cofe}) |> Repo.all()
|
||||
end
|
||||
|
||||
test "returns moderator users if they are privileged", %{
|
||||
moderator_user: moderator_user,
|
||||
admin_moderator_user: admin_moderator_user
|
||||
} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
clear_config([:instance, :moderator_privileges], [:cofe])
|
||||
|
||||
assert [_, _] = User.Query.build(%{is_privileged: :cofe}) |> Repo.all()
|
||||
assert moderator_user in (User.Query.build(%{is_privileged: :cofe}) |> Repo.all())
|
||||
assert admin_moderator_user in (User.Query.build(%{is_privileged: :cofe}) |> Repo.all())
|
||||
end
|
||||
|
||||
test "returns admin users if they are privileged", %{
|
||||
admin_user: admin_user,
|
||||
admin_moderator_user: admin_moderator_user
|
||||
} do
|
||||
clear_config([:instance, :admin_privileges], [:cofe])
|
||||
clear_config([:instance, :moderator_privileges], [])
|
||||
|
||||
assert [_, _] = User.Query.build(%{is_privileged: :cofe}) |> Repo.all()
|
||||
assert admin_user in (User.Query.build(%{is_privileged: :cofe}) |> Repo.all())
|
||||
assert admin_moderator_user in (User.Query.build(%{is_privileged: :cofe}) |> Repo.all())
|
||||
end
|
||||
|
||||
test "returns admin and moderator users if they are both privileged", %{
|
||||
moderator_user: moderator_user,
|
||||
admin_user: admin_user,
|
||||
admin_moderator_user: admin_moderator_user
|
||||
} do
|
||||
clear_config([:instance, :admin_privileges], [:cofe])
|
||||
clear_config([:instance, :moderator_privileges], [:cofe])
|
||||
|
||||
assert [_, _, _] = User.Query.build(%{is_privileged: :cofe}) |> Repo.all()
|
||||
assert admin_user in (User.Query.build(%{is_privileged: :cofe}) |> Repo.all())
|
||||
assert moderator_user in (User.Query.build(%{is_privileged: :cofe}) |> Repo.all())
|
||||
assert admin_moderator_user in (User.Query.build(%{is_privileged: :cofe}) |> Repo.all())
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.UserSearchTest do
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.User
|
||||
use Pleroma.DataCase
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
defmodule Pleroma.UserTest do
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Builders.UserBuilder
|
||||
alias Pleroma.Notification
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.Tests.ObanHelpers
|
||||
|
|
@ -13,7 +12,7 @@ defmodule Pleroma.UserTest do
|
|||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
use Pleroma.DataCase
|
||||
use Pleroma.DataCase, async: false
|
||||
use Oban.Testing, repo: Pleroma.Repo
|
||||
|
||||
import Pleroma.Factory
|
||||
|
|
@ -473,12 +472,7 @@ defmodule Pleroma.UserTest do
|
|||
reject_deletes: []
|
||||
)
|
||||
|
||||
setup do:
|
||||
clear_config(:mrf,
|
||||
policies: [
|
||||
Pleroma.Web.ActivityPub.MRF.SimplePolicy
|
||||
]
|
||||
)
|
||||
setup do: clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
|
||||
|
||||
test "it sends a welcome chat message when Simple policy applied to local instance" do
|
||||
clear_config([:mrf_simple, :media_nsfw], [{"localhost", ""}])
|
||||
|
|
@ -1850,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"},
|
||||
|
|
@ -1891,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,
|
||||
|
|
@ -2038,31 +2030,82 @@ defmodule Pleroma.UserTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "superuser?/1" do
|
||||
describe "privileged?/1" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:cofe, :suya])
|
||||
clear_config([:instance, :moderator_privileges], [:cofe, :suya])
|
||||
end
|
||||
|
||||
test "returns false for unprivileged users" do
|
||||
user = insert(:user, local: true)
|
||||
|
||||
refute User.superuser?(user)
|
||||
refute User.privileged?(user, :cofe)
|
||||
end
|
||||
|
||||
test "returns false for remote users" do
|
||||
user = insert(:user, local: false)
|
||||
remote_admin_user = insert(:user, local: false, is_admin: true)
|
||||
|
||||
refute User.superuser?(user)
|
||||
refute User.superuser?(remote_admin_user)
|
||||
refute User.privileged?(user, :cofe)
|
||||
refute User.privileged?(remote_admin_user, :cofe)
|
||||
end
|
||||
|
||||
test "returns true for local moderators" do
|
||||
test "returns true for local moderators if, and only if, they are privileged" do
|
||||
user = insert(:user, local: true, is_moderator: true)
|
||||
|
||||
assert User.superuser?(user)
|
||||
assert User.privileged?(user, :cofe)
|
||||
|
||||
clear_config([:instance, :moderator_privileges], [])
|
||||
|
||||
refute User.privileged?(user, :cofe)
|
||||
end
|
||||
|
||||
test "returns true for local admins" do
|
||||
test "returns true for local admins if, and only if, they are privileged" do
|
||||
user = insert(:user, local: true, is_admin: true)
|
||||
|
||||
assert User.superuser?(user)
|
||||
assert User.privileged?(user, :cofe)
|
||||
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
refute User.privileged?(user, :cofe)
|
||||
end
|
||||
end
|
||||
|
||||
describe "privileges/1" do
|
||||
setup do
|
||||
clear_config([:instance, :moderator_privileges], [:cofe, :only_moderator])
|
||||
clear_config([:instance, :admin_privileges], [:cofe, :only_admin])
|
||||
end
|
||||
|
||||
test "returns empty list for users without roles" do
|
||||
user = insert(:user, local: true)
|
||||
|
||||
assert [] == User.privileges(user)
|
||||
end
|
||||
|
||||
test "returns list of privileges for moderators" do
|
||||
moderator = insert(:user, is_moderator: true, local: true)
|
||||
|
||||
assert [:cofe, :only_moderator] == User.privileges(moderator) |> Enum.sort()
|
||||
end
|
||||
|
||||
test "returns list of privileges for admins" do
|
||||
admin = insert(:user, is_admin: true, local: true)
|
||||
|
||||
assert [:cofe, :only_admin] == User.privileges(admin) |> Enum.sort()
|
||||
end
|
||||
|
||||
test "returns list of unique privileges for users who are both moderator and admin" do
|
||||
moderator_admin = insert(:user, is_moderator: true, is_admin: true, local: true)
|
||||
|
||||
assert [:cofe, :only_admin, :only_moderator] ==
|
||||
User.privileges(moderator_admin) |> Enum.sort()
|
||||
end
|
||||
|
||||
test "returns empty list for remote users" do
|
||||
remote_moderator_admin = insert(:user, is_moderator: true, is_admin: true, local: false)
|
||||
|
||||
assert [] == User.privileges(remote_moderator_admin)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -2105,13 +2148,77 @@ defmodule Pleroma.UserTest do
|
|||
assert User.visible_for(user, other_user) == :visible
|
||||
end
|
||||
|
||||
test "returns true when the account is unconfirmed and being viewed by a privileged account (confirmation required)" do
|
||||
test "returns true when the account is unconfirmed and being viewed by a privileged account (privilege :users_manage_activation_state, confirmation required)" do
|
||||
clear_config([:instance, :account_activation_required], true)
|
||||
clear_config([:instance, :admin_privileges], [:users_manage_activation_state])
|
||||
|
||||
user = insert(:user, local: true, is_confirmed: false)
|
||||
other_user = insert(:user, local: true, is_admin: true)
|
||||
|
||||
assert User.visible_for(user, other_user) == :visible
|
||||
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
refute User.visible_for(user, other_user) == :visible
|
||||
end
|
||||
end
|
||||
|
||||
describe "all_users_with_privilege/1" do
|
||||
setup do
|
||||
%{
|
||||
user: insert(:user, local: true, is_admin: false, is_moderator: false),
|
||||
moderator_user: insert(:user, local: true, is_admin: false, is_moderator: true),
|
||||
admin_user: insert(:user, local: true, is_admin: true, is_moderator: false),
|
||||
admin_moderator_user: insert(:user, local: true, is_admin: true, is_moderator: true),
|
||||
remote_user: insert(:user, local: false, is_admin: true, is_moderator: true),
|
||||
non_active_user:
|
||||
insert(:user, local: true, is_admin: true, is_moderator: true, is_active: false)
|
||||
}
|
||||
end
|
||||
|
||||
test "doesn't return any users when there are no privileged roles" do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
clear_config([:instance, :moderator_privileges], [])
|
||||
|
||||
assert [] = User.Query.build(%{is_privileged: :cofe}) |> Repo.all()
|
||||
end
|
||||
|
||||
test "returns moderator users if they are privileged", %{
|
||||
moderator_user: moderator_user,
|
||||
admin_moderator_user: admin_moderator_user
|
||||
} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
clear_config([:instance, :moderator_privileges], [:cofe])
|
||||
|
||||
assert [_, _] = User.Query.build(%{is_privileged: :cofe}) |> Repo.all()
|
||||
assert moderator_user in User.all_users_with_privilege(:cofe)
|
||||
assert admin_moderator_user in User.all_users_with_privilege(:cofe)
|
||||
end
|
||||
|
||||
test "returns admin users if they are privileged", %{
|
||||
admin_user: admin_user,
|
||||
admin_moderator_user: admin_moderator_user
|
||||
} do
|
||||
clear_config([:instance, :admin_privileges], [:cofe])
|
||||
clear_config([:instance, :moderator_privileges], [])
|
||||
|
||||
assert [_, _] = User.Query.build(%{is_privileged: :cofe}) |> Repo.all()
|
||||
assert admin_user in User.all_users_with_privilege(:cofe)
|
||||
assert admin_moderator_user in User.all_users_with_privilege(:cofe)
|
||||
end
|
||||
|
||||
test "returns admin and moderator users if they are both privileged", %{
|
||||
moderator_user: moderator_user,
|
||||
admin_user: admin_user,
|
||||
admin_moderator_user: admin_moderator_user
|
||||
} do
|
||||
clear_config([:instance, :admin_privileges], [:cofe])
|
||||
clear_config([:instance, :moderator_privileges], [:cofe])
|
||||
|
||||
assert [_, _, _] = User.Query.build(%{is_privileged: :cofe}) |> Repo.all()
|
||||
assert admin_user in User.all_users_with_privilege(:cofe)
|
||||
assert moderator_user in User.all_users_with_privilege(:cofe)
|
||||
assert admin_moderator_user in User.all_users_with_privilege(:cofe)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -2351,26 +2458,6 @@ defmodule Pleroma.UserTest do
|
|||
assert {:ok, user} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
|
||||
assert %User{bio: "test-bio"} = User.get_cached_by_ap_id(user.ap_id)
|
||||
end
|
||||
|
||||
test "removes report notifs when user isn't superuser any more" do
|
||||
report_activity = insert(:report_activity)
|
||||
user = insert(:user, is_moderator: true, is_admin: true)
|
||||
{:ok, _} = Notification.create_notifications(report_activity)
|
||||
|
||||
assert [%Pleroma.Notification{type: "pleroma:report"}] = Notification.for_user(user)
|
||||
|
||||
{:ok, user} = user |> User.admin_api_update(%{is_moderator: false})
|
||||
# is still superuser because still admin
|
||||
assert [%Pleroma.Notification{type: "pleroma:report"}] = Notification.for_user(user)
|
||||
|
||||
{:ok, user} = user |> User.admin_api_update(%{is_moderator: true, is_admin: false})
|
||||
# is still superuser because still moderator
|
||||
assert [%Pleroma.Notification{type: "pleroma:report"}] = Notification.for_user(user)
|
||||
|
||||
{:ok, user} = user |> User.admin_api_update(%{is_moderator: false})
|
||||
# is not a superuser any more
|
||||
assert [] = Notification.for_user(user)
|
||||
end
|
||||
end
|
||||
|
||||
describe "following/followers synchronization" do
|
||||
|
|
@ -2384,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
|
||||
|
|
@ -2406,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
|
||||
|
|
@ -2428,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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -1342,6 +1341,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
%{test_file: test_file}
|
||||
end
|
||||
|
||||
test "strips / from filename", %{test_file: file} do
|
||||
file = %Plug.Upload{file | filename: "../../../../../nested/bad.jpg"}
|
||||
{:ok, %Object{} = object} = ActivityPub.upload(file)
|
||||
[%{"href" => href}] = object.data["url"]
|
||||
assert Regex.match?(~r"/bad.jpg$", href)
|
||||
refute Regex.match?(~r"/nested/", href)
|
||||
end
|
||||
|
||||
test "sets a description if given", %{test_file: file} do
|
||||
{:ok, %Object{} = object} = ActivityPub.upload(file, description: "a cool file")
|
||||
assert object.data["name"] == "a cool file"
|
||||
|
|
@ -2645,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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
425
test/pleroma/web/activity_pub/mrf/emoji_policy_test.exs
Normal file
425
test/pleroma/web/activity_pub/mrf/emoji_policy_test.exs
Normal file
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
112
test/pleroma/web/activity_pub/mrf/inline_quote_policy_test.exs
Normal file
112
test/pleroma/web/activity_pub/mrf/inline_quote_policy_test.exs
Normal file
|
|
@ -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
|
||||
|
|
@ -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
|
||||
19
test/pleroma/web/activity_pub/mrf/utils_test.exs
Normal file
19
test/pleroma/web/activity_pub/mrf/utils_test.exs
Normal file
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidationTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
use Pleroma.DataCase, async: false
|
||||
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Web.ActivityPub.Builder
|
||||
|
|
@ -90,17 +90,26 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidationTest do
|
|||
assert {:actor, {"is not allowed to modify object", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "it's valid if the actor of the object is a local superuser",
|
||||
test "it's only valid if the actor of the object is a privileged local user",
|
||||
%{valid_post_delete: valid_post_delete} do
|
||||
clear_config([:instance, :moderator_privileges], [:messages_delete])
|
||||
|
||||
user =
|
||||
insert(:user, local: true, is_moderator: true, ap_id: "https://gensokyo.2hu/users/raymoo")
|
||||
|
||||
valid_other_actor =
|
||||
post_delete_with_moderator_actor =
|
||||
valid_post_delete
|
||||
|> Map.put("actor", user.ap_id)
|
||||
|
||||
{:ok, _, meta} = ObjectValidator.validate(valid_other_actor, [])
|
||||
{:ok, _, meta} = ObjectValidator.validate(post_delete_with_moderator_actor, [])
|
||||
|
||||
assert meta[:do_not_federate]
|
||||
|
||||
clear_config([:instance, :moderator_privileges], [])
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(post_delete_with_moderator_actor, [])
|
||||
|
||||
assert {:actor, {"is not allowed to modify object", []}} in cng.errors
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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 {:content, {"must be a single character emoji", []}} in cng.errors
|
||||
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 {:tag, {"does not contain an Emoji tag", []}} in cng.errors
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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")
|
||||
|
||||
|
|
|
|||
|
|
@ -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"})
|
||||
})
|
||||
test "it prepares a quote post" do
|
||||
user = insert(:user)
|
||||
|
||||
user_two = insert(:user)
|
||||
Pleroma.FollowingRelationship.follow(user_two, user, :follow_accept)
|
||||
{:ok, quoted_post} = CommonAPI.post(user, %{status: "hey"})
|
||||
{:ok, quote_post} = CommonAPI.post(user, %{status: "hey", quote_id: quoted_post.id})
|
||||
|
||||
{: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
|
||||
{:ok, modified} = Transmogrifier.prepare_outgoing(quote_post.data)
|
||||
|
||||
user = User.get_cached_by_id(user.id)
|
||||
assert user.note_count == 1
|
||||
%{data: %{"id" => quote_id}} = Object.normalize(quoted_post)
|
||||
|
||||
{: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"
|
||||
|
||||
user = User.get_cached_by_id(user.id)
|
||||
assert user.note_count == 1
|
||||
|
||||
activity = Activity.get_by_id(activity.id)
|
||||
assert user.follower_address in activity.recipients
|
||||
|
||||
assert %{
|
||||
"url" => [
|
||||
%{
|
||||
"href" =>
|
||||
"https://cdn.niu.moe/accounts/avatars/000/033/323/original/fd7f8ae0b3ffedc9.jpeg"
|
||||
}
|
||||
]
|
||||
} = user.avatar
|
||||
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
||||
use Pleroma.Web.ConnCase
|
||||
use Pleroma.Web.ConnCase, async: false
|
||||
use Oban.Testing, repo: Pleroma.Repo
|
||||
|
||||
import ExUnit.CaptureLog
|
||||
|
|
@ -92,18 +92,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
|
||||
describe "PUT /api/pleroma/admin/users/tag" do
|
||||
setup %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [:users_manage_tags])
|
||||
|
||||
user1 = insert(:user, %{tags: ["x"]})
|
||||
user2 = insert(:user, %{tags: ["y"]})
|
||||
user3 = insert(:user, %{tags: ["unchanged"]})
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "application/json")
|
||||
|> put(
|
||||
"/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <>
|
||||
"#{user2.nickname}&tags[]=foo&tags[]=bar"
|
||||
)
|
||||
|
||||
%{conn: conn, user1: user1, user2: user2, user3: user3}
|
||||
end
|
||||
|
||||
|
|
@ -113,6 +107,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
user1: user1,
|
||||
user2: user2
|
||||
} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "application/json")
|
||||
|> put(
|
||||
"/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <>
|
||||
"#{user2.nickname}&tags[]=foo&tags[]=bar"
|
||||
)
|
||||
|
||||
assert empty_json_response(conn)
|
||||
assert User.get_cached_by_id(user1.id).tags == ["x", "foo", "bar"]
|
||||
assert User.get_cached_by_id(user2.id).tags == ["y", "foo", "bar"]
|
||||
|
|
@ -130,26 +132,43 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
"@#{admin.nickname} added tags: #{tags} to users: #{users}"
|
||||
end
|
||||
|
||||
test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
|
||||
test "it does not modify tags of not specified users", %{
|
||||
conn: conn,
|
||||
user1: user1,
|
||||
user2: user2,
|
||||
user3: user3
|
||||
} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "application/json")
|
||||
|> put(
|
||||
"/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <>
|
||||
"#{user2.nickname}&tags[]=foo&tags[]=bar"
|
||||
)
|
||||
|
||||
assert empty_json_response(conn)
|
||||
assert User.get_cached_by_id(user3.id).tags == ["unchanged"]
|
||||
end
|
||||
|
||||
test "it requires privileged role :users_manage_tags", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("accept", "application/json")
|
||||
|> put("/api/pleroma/admin/users/tag?nicknames[]=nickname&tags[]=foo&tags[]=bar")
|
||||
|
||||
assert json_response(response, :forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "DELETE /api/pleroma/admin/users/tag" do
|
||||
setup %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [:users_manage_tags])
|
||||
user1 = insert(:user, %{tags: ["x"]})
|
||||
user2 = insert(:user, %{tags: ["y", "z"]})
|
||||
user3 = insert(:user, %{tags: ["unchanged"]})
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "application/json")
|
||||
|> delete(
|
||||
"/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <>
|
||||
"#{user2.nickname}&tags[]=x&tags[]=z"
|
||||
)
|
||||
|
||||
%{conn: conn, user1: user1, user2: user2, user3: user3}
|
||||
end
|
||||
|
||||
|
|
@ -159,6 +178,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
user1: user1,
|
||||
user2: user2
|
||||
} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "application/json")
|
||||
|> delete(
|
||||
"/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <>
|
||||
"#{user2.nickname}&tags[]=x&tags[]=z"
|
||||
)
|
||||
|
||||
assert empty_json_response(conn)
|
||||
assert User.get_cached_by_id(user1.id).tags == []
|
||||
assert User.get_cached_by_id(user2.id).tags == ["y"]
|
||||
|
|
@ -176,10 +203,34 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
"@#{admin.nickname} removed tags: #{tags} from users: #{users}"
|
||||
end
|
||||
|
||||
test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
|
||||
test "it does not modify tags of not specified users", %{
|
||||
conn: conn,
|
||||
user1: user1,
|
||||
user2: user2,
|
||||
user3: user3
|
||||
} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "application/json")
|
||||
|> delete(
|
||||
"/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <>
|
||||
"#{user2.nickname}&tags[]=x&tags[]=z"
|
||||
)
|
||||
|
||||
assert empty_json_response(conn)
|
||||
assert User.get_cached_by_id(user3.id).tags == ["unchanged"]
|
||||
end
|
||||
|
||||
test "it requires privileged role :users_manage_tags", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("accept", "application/json")
|
||||
|> delete("/api/pleroma/admin/users/tag?nicknames[]=nickname&tags[]=foo&tags[]=bar")
|
||||
|
||||
assert json_response(response, :forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "/api/pleroma/admin/users/:nickname/permission_group" do
|
||||
|
|
@ -271,21 +322,38 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
test "/api/pleroma/admin/users/:nickname/password_reset", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
describe "/api/pleroma/admin/users/:nickname/password_reset" do
|
||||
test "it returns a password reset link", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [:users_manage_credentials])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "application/json")
|
||||
|> get("/api/pleroma/admin/users/#{user.nickname}/password_reset")
|
||||
user = insert(:user)
|
||||
|
||||
resp = json_response(conn, 200)
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "application/json")
|
||||
|> get("/api/pleroma/admin/users/#{user.nickname}/password_reset")
|
||||
|
||||
assert Regex.match?(~r/(http:\/\/|https:\/\/)/, resp["link"])
|
||||
resp = json_response(conn, 200)
|
||||
|
||||
assert Regex.match?(~r/(http:\/\/|https:\/\/)/, resp["link"])
|
||||
end
|
||||
|
||||
test "it requires privileged role :users_manage_credentials", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("accept", "application/json")
|
||||
|> get("/api/pleroma/admin/users/nickname/password_reset")
|
||||
|
||||
assert json_response(response, :forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "PUT disable_mfa" do
|
||||
test "returns 200 and disable 2fa", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [:users_manage_credentials])
|
||||
|
||||
user =
|
||||
insert(:user,
|
||||
multi_factor_authentication_settings: %MFA.Settings{
|
||||
|
|
@ -307,6 +375,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
end
|
||||
|
||||
test "returns 404 if user not found", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [:users_manage_credentials])
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put("/api/pleroma/admin/users/disable_mfa", %{nickname: "nickname"})
|
||||
|
|
@ -314,6 +384,16 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
|
||||
assert response == %{"error" => "Not found"}
|
||||
end
|
||||
|
||||
test "it requires privileged role :users_manage_credentials", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put("/api/pleroma/admin/users/disable_mfa", %{nickname: "nickname"})
|
||||
|
||||
assert json_response(response, :forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /api/pleroma/admin/restart" do
|
||||
|
|
@ -344,6 +424,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
|
||||
describe "GET /api/pleroma/admin/users/:nickname/statuses" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:messages_read])
|
||||
|
||||
user = insert(:user)
|
||||
|
||||
insert(:note_activity, user: user)
|
||||
|
|
@ -360,6 +442,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
assert length(activities) == 3
|
||||
end
|
||||
|
||||
test "it requires privileged role :messages_read", %{conn: conn, user: user} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses")
|
||||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
|
||||
test "renders user's statuses with pagination", %{conn: conn, user: user} do
|
||||
%{"total" => 3, "activities" => [activity1]} =
|
||||
conn
|
||||
|
|
@ -421,21 +511,32 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
|
||||
describe "GET /api/pleroma/admin/users/:nickname/chats" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:messages_read])
|
||||
|
||||
user = insert(:user)
|
||||
|
||||
%{user: user}
|
||||
end
|
||||
|
||||
test "renders user's chats", %{conn: conn, user: user} do
|
||||
recipients = insert_list(3, :user)
|
||||
|
||||
Enum.each(recipients, fn recipient ->
|
||||
CommonAPI.post_chat_message(user, recipient, "yo")
|
||||
end)
|
||||
|
||||
%{user: user}
|
||||
end
|
||||
|
||||
test "renders user's chats", %{conn: conn, user: user} do
|
||||
conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/chats")
|
||||
|
||||
assert json_response(conn, 200) |> length() == 3
|
||||
end
|
||||
|
||||
test "it requires privileged role :messages_read", %{conn: conn, user: user} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/chats")
|
||||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /api/pleroma/admin/users/:nickname/chats unauthorized" do
|
||||
|
|
@ -471,6 +572,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
|
||||
describe "GET /api/pleroma/admin/moderation_log" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:moderation_log_read])
|
||||
moderator = insert(:user, is_moderator: true)
|
||||
|
||||
%{moderator: moderator}
|
||||
|
|
@ -675,6 +777,15 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
assert get_in(first_entry, ["data", "message"]) ==
|
||||
"@#{moderator.nickname} unfollowed relay: https://example.org/relay"
|
||||
end
|
||||
|
||||
test "it requires privileged role :moderation_log_read", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
assert conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> get("/api/pleroma/admin/moderation_log")
|
||||
|> json_response(:forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
test "gets a remote users when [:instance, :limit_to_local_content] is set to :unauthenticated",
|
||||
|
|
@ -688,6 +799,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
|
||||
describe "GET /users/:nickname/credentials" do
|
||||
test "gets the user credentials", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [:users_manage_credentials])
|
||||
user = insert(:user)
|
||||
conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials")
|
||||
|
||||
|
|
@ -696,6 +808,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
end
|
||||
|
||||
test "returns 403 if requested by a non-admin" do
|
||||
clear_config([:instance, :admin_privileges], [:users_manage_credentials])
|
||||
user = insert(:user)
|
||||
|
||||
conn =
|
||||
|
|
@ -705,6 +818,16 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
|
||||
test "it requires privileged role :users_manage_credentials", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/api/pleroma/admin/users/nickname/credentials")
|
||||
|
||||
assert json_response(response, :forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "PATCH /users/:nickname/credentials" do
|
||||
|
|
@ -714,6 +837,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
end
|
||||
|
||||
test "changes password and email", %{conn: conn, admin: admin, user: user} do
|
||||
clear_config([:instance, :admin_privileges], [:users_manage_credentials])
|
||||
|
||||
assert user.password_reset_pending == false
|
||||
|
||||
conn =
|
||||
|
|
@ -756,6 +881,19 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
|
||||
test "returns 403 if not privileged with :users_manage_credentials", %{conn: conn, user: user} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn =
|
||||
patch(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials", %{
|
||||
"password" => "new_password",
|
||||
"email" => "new_email@example.com",
|
||||
"name" => "new_name"
|
||||
})
|
||||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
|
||||
test "changes actor type from permitted list", %{conn: conn, user: user} do
|
||||
assert user.actor_type == "Person"
|
||||
|
||||
|
|
@ -784,6 +922,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
|
||||
describe "PATCH /users/:nickname/force_password_reset" do
|
||||
test "sets password_reset_pending to true", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [:users_manage_credentials])
|
||||
user = insert(:user)
|
||||
assert user.password_reset_pending == false
|
||||
|
||||
|
|
@ -796,10 +935,21 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
|
||||
assert User.get_by_id(user.id).password_reset_pending == true
|
||||
end
|
||||
|
||||
test "it requires privileged role :users_manage_credentials", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
response =
|
||||
conn
|
||||
|> patch("/api/pleroma/admin/users/force_password_reset", %{nickname: "nickname"})
|
||||
|
||||
assert json_response(response, :forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "PATCH /confirm_email" do
|
||||
test "it confirms emails of two users", %{conn: conn, admin: admin} do
|
||||
clear_config([:instance, :admin_privileges], [:users_manage_credentials])
|
||||
[first_user, second_user] = insert_pair(:user, is_confirmed: false)
|
||||
|
||||
refute first_user.is_confirmed
|
||||
|
|
@ -826,10 +976,21 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
assert ModerationLog.get_log_entry_message(log_entry) ==
|
||||
"@#{admin.nickname} confirmed email for users: @#{first_user.nickname}, @#{second_user.nickname}"
|
||||
end
|
||||
|
||||
test "it requires privileged role :users_manage_credentials", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
response =
|
||||
conn
|
||||
|> patch("/api/pleroma/admin/users/confirm_email", %{nicknames: ["nickname"]})
|
||||
|
||||
assert json_response(response, :forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "PATCH /resend_confirmation_email" do
|
||||
test "it resend emails for two users", %{conn: conn, admin: admin} do
|
||||
clear_config([:instance, :admin_privileges], [:users_manage_credentials])
|
||||
[first_user, second_user] = insert_pair(:user, is_confirmed: false)
|
||||
|
||||
ret_conn =
|
||||
|
|
@ -855,9 +1016,23 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
|> Swoosh.Email.put_private(:hackney_options, ssl_options: [versions: [:"tlsv1.2"]])
|
||||
|> assert_email_sent()
|
||||
end
|
||||
|
||||
test "it requires privileged role :users_manage_credentials", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
response =
|
||||
conn
|
||||
|> patch("/api/pleroma/admin/users/resend_confirmation_email", %{nicknames: ["nickname"]})
|
||||
|
||||
assert json_response(response, :forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "/api/pleroma/admin/stats" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:statistics_read])
|
||||
end
|
||||
|
||||
test "status visibility count", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
CommonAPI.post(user, %{visibility: "public", status: "hey"})
|
||||
|
|
@ -890,6 +1065,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
assert %{"direct" => 0, "private" => 1, "public" => 0, "unlisted" => 1} =
|
||||
response["status_visibility"]
|
||||
end
|
||||
|
||||
test "it requires privileged role :statistics_read", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
assert conn
|
||||
|> get("/api/pleroma/admin/stats", instance: "lain.wired")
|
||||
|> json_response(:forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "/api/pleroma/backups" do
|
||||
|
|
@ -958,6 +1141,34 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
assert Repo.aggregate(Pleroma.User.Backup, :count) == 2
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /api/v1/pleroma/admin/reload_emoji" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:emoji_manage_emoji])
|
||||
|
||||
admin = insert(:user, is_admin: true)
|
||||
token = insert(:oauth_admin_token, user: admin)
|
||||
|
||||
conn =
|
||||
build_conn()
|
||||
|> assign(:user, admin)
|
||||
|> assign(:token, token)
|
||||
|
||||
{:ok, %{conn: conn, admin: admin}}
|
||||
end
|
||||
|
||||
test "it requires privileged role :emoji_manage_emoji", %{conn: conn} do
|
||||
assert conn
|
||||
|> post("/api/v1/pleroma/admin/reload_emoji")
|
||||
|> json_response(200)
|
||||
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
assert conn
|
||||
|> post("/api/v1/pleroma/admin/reload_emoji")
|
||||
|> json_response(:forbidden)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Needed for testing
|
||||
|
|
|
|||
|
|
@ -3,11 +3,12 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.AdminAPI.AnnouncementControllerTest do
|
||||
use Pleroma.Web.ConnCase
|
||||
use Pleroma.Web.ConnCase, async: false
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:announcements_manage_announcements])
|
||||
admin = insert(:user, is_admin: true)
|
||||
token = insert(:oauth_admin_token, user: admin)
|
||||
|
||||
|
|
@ -31,6 +32,18 @@ defmodule Pleroma.Web.AdminAPI.AnnouncementControllerTest do
|
|||
assert [%{"id" => ^id}] = response
|
||||
end
|
||||
|
||||
test "it requires privileged role :announcements_manage_announcements", %{conn: conn} do
|
||||
conn
|
||||
|> get("/api/v1/pleroma/admin/announcements")
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn
|
||||
|> get("/api/v1/pleroma/admin/announcements")
|
||||
|> json_response(:forbidden)
|
||||
end
|
||||
|
||||
test "it paginates announcements", %{conn: conn} do
|
||||
_announcements = Enum.map(0..20, fn _ -> insert(:announcement) end)
|
||||
|
||||
|
|
@ -92,6 +105,20 @@ defmodule Pleroma.Web.AdminAPI.AnnouncementControllerTest do
|
|||
assert %{"id" => ^id} = response
|
||||
end
|
||||
|
||||
test "it requires privileged role :announcements_manage_announcements", %{conn: conn} do
|
||||
%{id: id} = insert(:announcement)
|
||||
|
||||
conn
|
||||
|> get("/api/v1/pleroma/admin/announcements/#{id}")
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn
|
||||
|> get("/api/v1/pleroma/admin/announcements/#{id}")
|
||||
|> json_response(:forbidden)
|
||||
end
|
||||
|
||||
test "it returns not found for non-existent id", %{conn: conn} do
|
||||
%{id: id} = insert(:announcement)
|
||||
|
||||
|
|
@ -112,6 +139,20 @@ defmodule Pleroma.Web.AdminAPI.AnnouncementControllerTest do
|
|||
|> json_response_and_validate_schema(:ok)
|
||||
end
|
||||
|
||||
test "it requires privileged role :announcements_manage_announcements", %{conn: conn} do
|
||||
%{id: id} = insert(:announcement)
|
||||
|
||||
conn
|
||||
|> delete("/api/v1/pleroma/admin/announcements/#{id}")
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn
|
||||
|> delete("/api/v1/pleroma/admin/announcements/#{id}")
|
||||
|> json_response(:forbidden)
|
||||
end
|
||||
|
||||
test "it returns not found for non-existent id", %{conn: conn} do
|
||||
%{id: id} = insert(:announcement)
|
||||
|
||||
|
|
@ -156,6 +197,29 @@ defmodule Pleroma.Web.AdminAPI.AnnouncementControllerTest do
|
|||
assert NaiveDateTime.compare(new.starts_at, starts_at) == :eq
|
||||
end
|
||||
|
||||
test "it requires privileged role :announcements_manage_announcements", %{conn: conn} do
|
||||
%{id: id} = insert(:announcement)
|
||||
|
||||
now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
|
||||
starts_at = NaiveDateTime.add(now, -10, :second)
|
||||
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch("/api/v1/pleroma/admin/announcements/#{id}", %{
|
||||
starts_at: NaiveDateTime.to_iso8601(starts_at)
|
||||
})
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch("/api/v1/pleroma/admin/announcements/#{id}", %{
|
||||
starts_at: NaiveDateTime.to_iso8601(starts_at)
|
||||
})
|
||||
|> json_response(:forbidden)
|
||||
end
|
||||
|
||||
test "it updates with time with utc timezone", %{conn: conn} do
|
||||
%{id: id} = insert(:announcement)
|
||||
|
||||
|
|
@ -250,6 +314,36 @@ defmodule Pleroma.Web.AdminAPI.AnnouncementControllerTest do
|
|||
assert NaiveDateTime.compare(announcement.ends_at, ends_at) == :eq
|
||||
end
|
||||
|
||||
test "it requires privileged role :announcements_manage_announcements", %{conn: conn} do
|
||||
content = "test post announcement api"
|
||||
|
||||
now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
|
||||
starts_at = NaiveDateTime.add(now, -10, :second)
|
||||
ends_at = NaiveDateTime.add(now, 10, :second)
|
||||
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/pleroma/admin/announcements", %{
|
||||
"content" => content,
|
||||
"starts_at" => NaiveDateTime.to_iso8601(starts_at),
|
||||
"ends_at" => NaiveDateTime.to_iso8601(ends_at),
|
||||
"all_day" => true
|
||||
})
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/pleroma/admin/announcements", %{
|
||||
"content" => content,
|
||||
"starts_at" => NaiveDateTime.to_iso8601(starts_at),
|
||||
"ends_at" => NaiveDateTime.to_iso8601(ends_at),
|
||||
"all_day" => true
|
||||
})
|
||||
|> json_response(:forbidden)
|
||||
end
|
||||
|
||||
test "creating with time with utc timezones", %{conn: conn} do
|
||||
content = "test post announcement api"
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.AdminAPI.ChatControllerTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
use Pleroma.Web.ConnCase, async: false
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
|
|
@ -27,7 +27,10 @@ defmodule Pleroma.Web.AdminAPI.ChatControllerTest do
|
|||
end
|
||||
|
||||
describe "DELETE /api/pleroma/admin/chats/:id/messages/:message_id" do
|
||||
setup do: admin_setup()
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:messages_delete])
|
||||
admin_setup()
|
||||
end
|
||||
|
||||
test "it deletes a message from the chat", %{conn: conn, admin: admin} do
|
||||
user = insert(:user)
|
||||
|
|
@ -60,10 +63,22 @@ defmodule Pleroma.Web.AdminAPI.ChatControllerTest do
|
|||
refute MessageReference.get_by_id(recipient_cm_ref.id)
|
||||
assert %{data: %{"type" => "Tombstone"}} = Object.get_by_id(object.id)
|
||||
end
|
||||
|
||||
test "it requires privileged role :messages_delete", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
assert conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> delete("/api/pleroma/admin/chats/some_id/messages/some_ref_id")
|
||||
|> json_response(:forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /api/pleroma/admin/chats/:id/messages" do
|
||||
setup do: admin_setup()
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:messages_read])
|
||||
admin_setup()
|
||||
end
|
||||
|
||||
test "it paginates", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
|
@ -114,10 +129,21 @@ defmodule Pleroma.Web.AdminAPI.ChatControllerTest do
|
|||
|
||||
assert length(result) == 3
|
||||
end
|
||||
|
||||
test "it requires privileged role :messages_read", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn = get(conn, "/api/pleroma/admin/chats/some_id/messages")
|
||||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /api/pleroma/admin/chats/:id" do
|
||||
setup do: admin_setup()
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:messages_read])
|
||||
admin_setup()
|
||||
end
|
||||
|
||||
test "it returns a chat", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
|
@ -135,6 +161,14 @@ defmodule Pleroma.Web.AdminAPI.ChatControllerTest do
|
|||
assert %{} = result["receiver"]
|
||||
refute result["account"]
|
||||
end
|
||||
|
||||
test "it requires privileged role :messages_read", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn = get(conn, "/api/pleroma/admin/chats/some_id")
|
||||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "unauthorized chat moderation" do
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.AdminAPI.InstanceControllerTest do
|
||||
use Pleroma.Web.ConnCase
|
||||
use Pleroma.Web.ConnCase, async: false
|
||||
use Oban.Testing, repo: Pleroma.Repo
|
||||
|
||||
import Pleroma.Factory
|
||||
|
|
@ -31,6 +31,7 @@ defmodule Pleroma.Web.AdminAPI.InstanceControllerTest do
|
|||
end
|
||||
|
||||
test "GET /instances/:instance/statuses", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [:messages_read])
|
||||
user = insert(:user, local: false, ap_id: "https://archae.me/users/archaeme")
|
||||
user2 = insert(:user, local: false, ap_id: "https://test.com/users/test")
|
||||
insert_pair(:note_activity, user: user)
|
||||
|
|
@ -60,9 +61,14 @@ defmodule Pleroma.Web.AdminAPI.InstanceControllerTest do
|
|||
|> json_response(200)
|
||||
|
||||
assert length(activities) == 3
|
||||
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn |> get("/api/pleroma/admin/instances/archae.me/statuses") |> json_response(:forbidden)
|
||||
end
|
||||
|
||||
test "DELETE /instances/:instance", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [:instances_delete])
|
||||
user = insert(:user, nickname: "lain@lain.com")
|
||||
post = insert(:note_activity, user: user)
|
||||
|
||||
|
|
@ -76,5 +82,11 @@ defmodule Pleroma.Web.AdminAPI.InstanceControllerTest do
|
|||
assert response == "lain.com"
|
||||
refute Repo.reload(user).is_active
|
||||
refute Repo.reload(post)
|
||||
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn
|
||||
|> delete("/api/pleroma/admin/instances/lain.com")
|
||||
|> json_response(:forbidden)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.AdminAPI.InviteControllerTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
use Pleroma.Web.ConnCase, async: false
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
|
|
@ -23,8 +23,25 @@ defmodule Pleroma.Web.AdminAPI.InviteControllerTest do
|
|||
end
|
||||
|
||||
describe "POST /api/pleroma/admin/users/email_invite, with valid config" do
|
||||
setup do: clear_config([:instance, :registrations_open], false)
|
||||
setup do: clear_config([:instance, :invites_enabled], true)
|
||||
setup do
|
||||
clear_config([:instance, :registrations_open], false)
|
||||
clear_config([:instance, :invites_enabled], true)
|
||||
clear_config([:instance, :admin_privileges], [:users_manage_invites])
|
||||
end
|
||||
|
||||
test "returns 403 if not privileged with :users_manage_invites", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json;charset=utf-8")
|
||||
|> post("/api/pleroma/admin/users/email_invite", %{
|
||||
email: "foo@bar.com",
|
||||
name: "J. D."
|
||||
})
|
||||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
|
||||
test "sends invitation and returns 204", %{admin: admin, conn: conn} do
|
||||
recipient_email = "foo@bar.com"
|
||||
|
|
@ -114,8 +131,11 @@ defmodule Pleroma.Web.AdminAPI.InviteControllerTest do
|
|||
end
|
||||
|
||||
describe "POST /api/pleroma/admin/users/email_invite, with invalid config" do
|
||||
setup do: clear_config([:instance, :registrations_open])
|
||||
setup do: clear_config([:instance, :invites_enabled])
|
||||
setup do
|
||||
clear_config([:instance, :registrations_open])
|
||||
clear_config([:instance, :invites_enabled])
|
||||
clear_config([:instance, :admin_privileges], [:users_manage_invites])
|
||||
end
|
||||
|
||||
test "it returns 500 if `invites_enabled` is not enabled", %{conn: conn} do
|
||||
clear_config([:instance, :registrations_open], false)
|
||||
|
|
@ -157,6 +177,21 @@ defmodule Pleroma.Web.AdminAPI.InviteControllerTest do
|
|||
end
|
||||
|
||||
describe "POST /api/pleroma/admin/users/invite_token" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:users_manage_invites])
|
||||
end
|
||||
|
||||
test "returns 403 if not privileged with :users_manage_invites", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/pleroma/admin/users/invite_token")
|
||||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
|
||||
test "without options", %{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|
|
@ -221,6 +256,18 @@ defmodule Pleroma.Web.AdminAPI.InviteControllerTest do
|
|||
end
|
||||
|
||||
describe "GET /api/pleroma/admin/users/invites" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:users_manage_invites])
|
||||
end
|
||||
|
||||
test "returns 403 if not privileged with :users_manage_invites", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn = get(conn, "/api/pleroma/admin/users/invites")
|
||||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
|
||||
test "no invites", %{conn: conn} do
|
||||
conn = get(conn, "/api/pleroma/admin/users/invites")
|
||||
|
||||
|
|
@ -249,6 +296,21 @@ defmodule Pleroma.Web.AdminAPI.InviteControllerTest do
|
|||
end
|
||||
|
||||
describe "POST /api/pleroma/admin/users/revoke_invite" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:users_manage_invites])
|
||||
end
|
||||
|
||||
test "returns 403 if not privileged with :users_manage_invites", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/pleroma/admin/users/revoke_invite", %{"token" => "foo"})
|
||||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
|
||||
test "with token", %{conn: conn} do
|
||||
{:ok, invite} = UserInviteToken.create_invite()
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.AdminAPI.ReportControllerTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
use Pleroma.Web.ConnCase, async: false
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
|
|
@ -26,6 +26,20 @@ defmodule Pleroma.Web.AdminAPI.ReportControllerTest do
|
|||
end
|
||||
|
||||
describe "GET /api/pleroma/admin/reports/:id" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:reports_manage_reports])
|
||||
end
|
||||
|
||||
test "returns 403 if not privileged with :reports_manage_reports", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> get("/api/pleroma/admin/reports/report_id")
|
||||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
|
||||
test "returns report by its id", %{conn: conn} do
|
||||
[reporter, target_user] = insert_pair(:user)
|
||||
activity = insert(:note_activity, user: target_user)
|
||||
|
|
@ -89,6 +103,8 @@ defmodule Pleroma.Web.AdminAPI.ReportControllerTest do
|
|||
|
||||
describe "PATCH /api/pleroma/admin/reports" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:reports_manage_reports])
|
||||
|
||||
[reporter, target_user] = insert_pair(:user)
|
||||
activity = insert(:note_activity, user: target_user)
|
||||
|
||||
|
|
@ -107,11 +123,30 @@ defmodule Pleroma.Web.AdminAPI.ReportControllerTest do
|
|||
})
|
||||
|
||||
%{
|
||||
reporter: reporter,
|
||||
id: report_id,
|
||||
second_report_id: second_report_id
|
||||
}
|
||||
end
|
||||
|
||||
test "returns 403 if not privileged with :reports_manage_reports", %{
|
||||
conn: conn,
|
||||
id: id,
|
||||
admin: admin
|
||||
} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:token, insert(:oauth_token, user: admin, scopes: ["admin:write:reports"]))
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch("/api/pleroma/admin/reports", %{
|
||||
"reports" => [%{"state" => "resolved", "id" => id}]
|
||||
})
|
||||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
|
||||
test "requires admin:write:reports scope", %{conn: conn, id: id, admin: admin} do
|
||||
read_token = insert(:oauth_token, user: admin, scopes: ["admin:read"])
|
||||
write_token = insert(:oauth_token, user: admin, scopes: ["admin:write:reports"])
|
||||
|
|
@ -232,9 +267,43 @@ 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
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:reports_manage_reports])
|
||||
end
|
||||
|
||||
test "returns 403 if not privileged with :reports_manage_reports", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> get(report_path(conn, :index))
|
||||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
|
||||
test "returns empty response when no reports created", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|
|
@ -318,6 +387,34 @@ defmodule Pleroma.Web.AdminAPI.ReportControllerTest do
|
|||
|> json_response_and_validate_schema(:ok)
|
||||
end
|
||||
|
||||
test "renders content correctly", %{conn: conn} do
|
||||
[reporter, target_user] = insert_pair(:user)
|
||||
note = insert(:note, user: target_user, data: %{"content" => "mew 1"})
|
||||
note2 = insert(:note, user: target_user, data: %{"content" => "mew 2"})
|
||||
activity = insert(:note_activity, user: target_user, note: note)
|
||||
activity2 = insert(:note_activity, user: target_user, note: note2)
|
||||
|
||||
{:ok, _report} =
|
||||
CommonAPI.report(reporter, %{
|
||||
account_id: target_user.id,
|
||||
comment: "I feel offended",
|
||||
status_ids: [activity.id, activity2.id]
|
||||
})
|
||||
|
||||
CommonAPI.delete(activity.id, target_user)
|
||||
CommonAPI.delete(activity2.id, target_user)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get(report_path(conn, :index))
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
assert [open_report] = response["reports"]
|
||||
assert %{"statuses" => [s1, s2]} = open_report
|
||||
assert "mew 1" in [s1["content"], s2["content"]]
|
||||
assert "mew 2" in [s1["content"], s2["content"]]
|
||||
end
|
||||
|
||||
test "returns 403 when requested by a non-admin" do
|
||||
user = insert(:user)
|
||||
token = insert(:oauth_token, user: user)
|
||||
|
|
@ -343,6 +440,8 @@ defmodule Pleroma.Web.AdminAPI.ReportControllerTest do
|
|||
|
||||
describe "POST /api/pleroma/admin/reports/:id/notes" do
|
||||
setup %{conn: conn, admin: admin} do
|
||||
clear_config([:instance, :admin_privileges], [:reports_manage_reports])
|
||||
|
||||
[reporter, target_user] = insert_pair(:user)
|
||||
activity = insert(:note_activity, user: target_user)
|
||||
|
||||
|
|
@ -371,6 +470,25 @@ defmodule Pleroma.Web.AdminAPI.ReportControllerTest do
|
|||
}
|
||||
end
|
||||
|
||||
test "returns 403 if not privileged with :reports_manage_reports", %{
|
||||
conn: conn,
|
||||
report_id: report_id
|
||||
} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
post_conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/pleroma/admin/reports/#{report_id}/notes", %{
|
||||
content: "this is disgusting2!"
|
||||
})
|
||||
|
||||
delete_conn = delete(conn, "/api/pleroma/admin/reports/#{report_id}/notes/note.id")
|
||||
|
||||
assert json_response(post_conn, :forbidden)
|
||||
assert json_response(delete_conn, :forbidden)
|
||||
end
|
||||
|
||||
test "it creates report note", %{admin_id: admin_id, report_id: report_id} do
|
||||
assert [note, _] = Repo.all(ReportNote)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.AdminAPI.StatusControllerTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
use Pleroma.Web.ConnCase, async: false
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
|
|
@ -26,6 +26,10 @@ defmodule Pleroma.Web.AdminAPI.StatusControllerTest do
|
|||
end
|
||||
|
||||
describe "GET /api/pleroma/admin/statuses/:id" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:messages_read])
|
||||
end
|
||||
|
||||
test "not found", %{conn: conn} do
|
||||
assert conn
|
||||
|> get("/api/pleroma/admin/statuses/not_found")
|
||||
|
|
@ -50,10 +54,17 @@ defmodule Pleroma.Web.AdminAPI.StatusControllerTest do
|
|||
assert account["is_active"] == actor.is_active
|
||||
assert account["is_confirmed"] == actor.is_confirmed
|
||||
end
|
||||
|
||||
test "denies reading activity when not privileged", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
assert conn |> get("/api/pleroma/admin/statuses/some_id") |> json_response(:forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "PUT /api/pleroma/admin/statuses/:id" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:messages_delete])
|
||||
activity = insert(:note_activity)
|
||||
|
||||
%{id: activity.id}
|
||||
|
|
@ -122,10 +133,20 @@ defmodule Pleroma.Web.AdminAPI.StatusControllerTest do
|
|||
assert %{"error" => "test - Invalid value for enum."} =
|
||||
json_response_and_validate_schema(conn, :bad_request)
|
||||
end
|
||||
|
||||
test "it requires privileged role :messages_delete", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
assert conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/pleroma/admin/statuses/some_id", %{})
|
||||
|> json_response(:forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "DELETE /api/pleroma/admin/statuses/:id" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:messages_delete])
|
||||
activity = insert(:note_activity)
|
||||
|
||||
%{id: activity.id}
|
||||
|
|
@ -149,9 +170,22 @@ defmodule Pleroma.Web.AdminAPI.StatusControllerTest do
|
|||
|
||||
assert json_response_and_validate_schema(conn, :not_found) == %{"error" => "Not found"}
|
||||
end
|
||||
|
||||
test "it requires privileged role :messages_delete", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
assert conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> delete("/api/pleroma/admin/statuses/some_id")
|
||||
|> json_response(:forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /api/pleroma/admin/statuses" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:messages_read])
|
||||
end
|
||||
|
||||
test "returns all public and unlisted statuses", %{conn: conn, admin: admin} do
|
||||
blocked = insert(:user)
|
||||
user = insert(:user)
|
||||
|
|
@ -197,5 +231,13 @@ defmodule Pleroma.Web.AdminAPI.StatusControllerTest do
|
|||
conn = get(conn, "/api/pleroma/admin/statuses?godmode=true")
|
||||
assert json_response_and_validate_schema(conn, 200) |> length() == 3
|
||||
end
|
||||
|
||||
test "it requires privileged role :messages_read", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn = get(conn, "/api/pleroma/admin/statuses")
|
||||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.AdminAPI.UserControllerTest do
|
||||
use Pleroma.Web.ConnCase
|
||||
use Pleroma.Web.ConnCase, async: false
|
||||
use Oban.Testing, repo: Pleroma.Repo
|
||||
|
||||
import Mock
|
||||
|
|
@ -38,6 +38,7 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do
|
|||
end
|
||||
|
||||
test "with valid `admin_token` query parameter, skips OAuth scopes check" do
|
||||
clear_config([:instance, :admin_privileges], [:users_read])
|
||||
clear_config([:admin_token], "password123")
|
||||
|
||||
user = insert(:user)
|
||||
|
|
@ -47,53 +48,10 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do
|
|||
assert json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
|
||||
test "GET /api/pleroma/admin/users/:nickname requires admin:read:accounts or broader scope",
|
||||
%{admin: admin} do
|
||||
user = insert(:user)
|
||||
url = "/api/pleroma/admin/users/#{user.nickname}"
|
||||
|
||||
good_token1 = insert(:oauth_token, user: admin, scopes: ["admin"])
|
||||
good_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read"])
|
||||
good_token3 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts"])
|
||||
|
||||
bad_token1 = insert(:oauth_token, user: admin, scopes: ["read:accounts"])
|
||||
bad_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts:partial"])
|
||||
bad_token3 = nil
|
||||
|
||||
for good_token <- [good_token1, good_token2, good_token3] do
|
||||
conn =
|
||||
build_conn()
|
||||
|> assign(:user, admin)
|
||||
|> assign(:token, good_token)
|
||||
|> get(url)
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
|
||||
for good_token <- [good_token1, good_token2, good_token3] do
|
||||
conn =
|
||||
build_conn()
|
||||
|> assign(:user, nil)
|
||||
|> assign(:token, good_token)
|
||||
|> get(url)
|
||||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
|
||||
for bad_token <- [bad_token1, bad_token2, bad_token3] do
|
||||
conn =
|
||||
build_conn()
|
||||
|> assign(:user, admin)
|
||||
|> assign(:token, bad_token)
|
||||
|> get(url)
|
||||
|
||||
assert json_response_and_validate_schema(conn, :forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "DELETE /api/pleroma/admin/users" do
|
||||
test "single user", %{admin: admin, conn: conn} do
|
||||
clear_config([:instance, :federating], true)
|
||||
clear_config([:instance, :admin_privileges], [:users_delete])
|
||||
|
||||
user =
|
||||
insert(:user,
|
||||
|
|
@ -149,6 +107,8 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do
|
|||
end
|
||||
|
||||
test "multiple users", %{admin: admin, conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [:users_delete])
|
||||
|
||||
user_one = insert(:user)
|
||||
user_two = insert(:user)
|
||||
|
||||
|
|
@ -168,6 +128,17 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do
|
|||
|
||||
assert response -- [user_one.nickname, user_two.nickname] == []
|
||||
end
|
||||
|
||||
test "Needs privileged role", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("accept", "application/json")
|
||||
|> delete("/api/pleroma/admin/users?nickname=nickname")
|
||||
|
||||
assert json_response(response, :forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "/api/pleroma/admin/users" do
|
||||
|
|
@ -307,7 +278,19 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "/api/pleroma/admin/users/:nickname" do
|
||||
describe "GET /api/pleroma/admin/users/:nickname" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:users_read])
|
||||
end
|
||||
|
||||
test "returns 403 if not privileged with :users_read", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn = get(conn, "/api/pleroma/admin/users/user.nickname")
|
||||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
|
||||
test "Show", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
|
|
@ -323,6 +306,50 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do
|
|||
|
||||
assert %{"error" => "Not found"} == json_response_and_validate_schema(conn, 404)
|
||||
end
|
||||
|
||||
test "requires admin:read:accounts or broader scope",
|
||||
%{admin: admin} do
|
||||
user = insert(:user)
|
||||
url = "/api/pleroma/admin/users/#{user.nickname}"
|
||||
|
||||
good_token1 = insert(:oauth_token, user: admin, scopes: ["admin"])
|
||||
good_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read"])
|
||||
good_token3 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts"])
|
||||
|
||||
bad_token1 = insert(:oauth_token, user: admin, scopes: ["read:accounts"])
|
||||
bad_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts:partial"])
|
||||
bad_token3 = nil
|
||||
|
||||
for good_token <- [good_token1, good_token2, good_token3] do
|
||||
conn =
|
||||
build_conn()
|
||||
|> assign(:user, admin)
|
||||
|> assign(:token, good_token)
|
||||
|> get(url)
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
|
||||
for good_token <- [good_token1, good_token2, good_token3] do
|
||||
conn =
|
||||
build_conn()
|
||||
|> assign(:user, nil)
|
||||
|> assign(:token, good_token)
|
||||
|> get(url)
|
||||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
|
||||
for bad_token <- [bad_token1, bad_token2, bad_token3] do
|
||||
conn =
|
||||
build_conn()
|
||||
|> assign(:user, admin)
|
||||
|> assign(:token, bad_token)
|
||||
|> get(url)
|
||||
|
||||
assert json_response_and_validate_schema(conn, :forbidden)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "/api/pleroma/admin/users/follow" do
|
||||
|
|
@ -378,6 +405,18 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do
|
|||
end
|
||||
|
||||
describe "GET /api/pleroma/admin/users" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:users_read])
|
||||
end
|
||||
|
||||
test "returns 403 if not privileged with :users_read", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn = get(conn, "/api/pleroma/admin/users?page=1")
|
||||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
|
||||
test "renders users array for the first page", %{conn: conn, admin: admin} do
|
||||
user = insert(:user, local: false, tags: ["foo", "bar"])
|
||||
user2 = insert(:user, is_approved: false, registration_reason: "I'm a chill dude")
|
||||
|
|
@ -810,49 +849,9 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
test "PATCH /api/pleroma/admin/users/activate", %{admin: admin, conn: conn} do
|
||||
user_one = insert(:user, is_active: false)
|
||||
user_two = insert(:user, is_active: false)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch(
|
||||
"/api/pleroma/admin/users/activate",
|
||||
%{nicknames: [user_one.nickname, user_two.nickname]}
|
||||
)
|
||||
|
||||
response = json_response_and_validate_schema(conn, 200)
|
||||
assert Enum.map(response["users"], & &1["is_active"]) == [true, true]
|
||||
|
||||
log_entry = Repo.one(ModerationLog)
|
||||
|
||||
assert ModerationLog.get_log_entry_message(log_entry) ==
|
||||
"@#{admin.nickname} activated users: @#{user_one.nickname}, @#{user_two.nickname}"
|
||||
end
|
||||
|
||||
test "PATCH /api/pleroma/admin/users/deactivate", %{admin: admin, conn: conn} do
|
||||
user_one = insert(:user, is_active: true)
|
||||
user_two = insert(:user, is_active: true)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch(
|
||||
"/api/pleroma/admin/users/deactivate",
|
||||
%{nicknames: [user_one.nickname, user_two.nickname]}
|
||||
)
|
||||
|
||||
response = json_response_and_validate_schema(conn, 200)
|
||||
assert Enum.map(response["users"], & &1["is_active"]) == [false, false]
|
||||
|
||||
log_entry = Repo.one(ModerationLog)
|
||||
|
||||
assert ModerationLog.get_log_entry_message(log_entry) ==
|
||||
"@#{admin.nickname} deactivated users: @#{user_one.nickname}, @#{user_two.nickname}"
|
||||
end
|
||||
|
||||
test "PATCH /api/pleroma/admin/users/approve", %{admin: admin, conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [:users_manage_invites])
|
||||
|
||||
user_one = insert(:user, is_approved: false)
|
||||
user_two = insert(:user, is_approved: false)
|
||||
|
||||
|
|
@ -873,6 +872,21 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do
|
|||
"@#{admin.nickname} approved users: @#{user_one.nickname}, @#{user_two.nickname}"
|
||||
end
|
||||
|
||||
test "PATCH /api/pleroma/admin/users/approve returns 403 if not privileged with :users_manage_invites",
|
||||
%{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch(
|
||||
"/api/pleroma/admin/users/approve",
|
||||
%{nicknames: ["user_one.nickname", "user_two.nickname"]}
|
||||
)
|
||||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
|
||||
test "PATCH /api/pleroma/admin/users/suggest", %{admin: admin, conn: conn} do
|
||||
user1 = insert(:user, is_suggested: false)
|
||||
user2 = insert(:user, is_suggested: false)
|
||||
|
|
@ -923,24 +937,113 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do
|
|||
"@#{admin.nickname} removed suggested users: @#{user1.nickname}, @#{user2.nickname}"
|
||||
end
|
||||
|
||||
test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation", %{admin: admin, conn: conn} do
|
||||
user = insert(:user)
|
||||
describe "user activation" do
|
||||
test "PATCH /api/pleroma/admin/users/activate", %{admin: admin, conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [:users_manage_activation_state])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch("/api/pleroma/admin/users/#{user.nickname}/toggle_activation")
|
||||
user_one = insert(:user, is_active: false)
|
||||
user_two = insert(:user, is_active: false)
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200) ==
|
||||
user_response(
|
||||
user,
|
||||
%{"is_active" => !user.is_active}
|
||||
)
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch(
|
||||
"/api/pleroma/admin/users/activate",
|
||||
%{nicknames: [user_one.nickname, user_two.nickname]}
|
||||
)
|
||||
|
||||
log_entry = Repo.one(ModerationLog)
|
||||
response = json_response_and_validate_schema(conn, 200)
|
||||
assert Enum.map(response["users"], & &1["is_active"]) == [true, true]
|
||||
|
||||
assert ModerationLog.get_log_entry_message(log_entry) ==
|
||||
"@#{admin.nickname} deactivated users: @#{user.nickname}"
|
||||
log_entry = Repo.one(ModerationLog)
|
||||
|
||||
assert ModerationLog.get_log_entry_message(log_entry) ==
|
||||
"@#{admin.nickname} activated users: @#{user_one.nickname}, @#{user_two.nickname}"
|
||||
end
|
||||
|
||||
test "PATCH /api/pleroma/admin/users/deactivate", %{admin: admin, conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [:users_manage_activation_state])
|
||||
|
||||
user_one = insert(:user, is_active: true)
|
||||
user_two = insert(:user, is_active: true)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch(
|
||||
"/api/pleroma/admin/users/deactivate",
|
||||
%{nicknames: [user_one.nickname, user_two.nickname]}
|
||||
)
|
||||
|
||||
response = json_response_and_validate_schema(conn, 200)
|
||||
assert Enum.map(response["users"], & &1["is_active"]) == [false, false]
|
||||
|
||||
log_entry = Repo.one(ModerationLog)
|
||||
|
||||
assert ModerationLog.get_log_entry_message(log_entry) ==
|
||||
"@#{admin.nickname} deactivated users: @#{user_one.nickname}, @#{user_two.nickname}"
|
||||
end
|
||||
|
||||
test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation", %{admin: admin, conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [:users_manage_activation_state])
|
||||
|
||||
user = insert(:user)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch("/api/pleroma/admin/users/#{user.nickname}/toggle_activation")
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200) ==
|
||||
user_response(
|
||||
user,
|
||||
%{"is_active" => !user.is_active}
|
||||
)
|
||||
|
||||
log_entry = Repo.one(ModerationLog)
|
||||
|
||||
assert ModerationLog.get_log_entry_message(log_entry) ==
|
||||
"@#{admin.nickname} deactivated users: @#{user.nickname}"
|
||||
end
|
||||
|
||||
test "it requires privileged role :statuses_activation to activate", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch(
|
||||
"/api/pleroma/admin/users/activate",
|
||||
%{nicknames: ["user_one.nickname", "user_two.nickname"]}
|
||||
)
|
||||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
|
||||
test "it requires privileged role :statuses_activation to deactivate", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch(
|
||||
"/api/pleroma/admin/users/deactivate",
|
||||
%{nicknames: ["user_one.nickname", "user_two.nickname"]}
|
||||
)
|
||||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
|
||||
test "it requires privileged role :statuses_activation to toggle activation", %{conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch("/api/pleroma/admin/users/user.nickname/toggle_activation")
|
||||
|
||||
assert json_response(conn, :forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
defp user_response(user, attrs \\ %{}) do
|
||||
|
|
|
|||
56
test/pleroma/web/api_spec/scopes/compiler_test.exs
Normal file
56
test/pleroma/web/api_spec/scopes/compiler_test.exs
Normal file
|
|
@ -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
|
||||
33
test/pleroma/web/common_api/activity_draft_test.exs
Normal file
33
test/pleroma/web/common_api/activity_draft_test.exs
Normal file
|
|
@ -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
|
||||
|
|
@ -178,6 +178,10 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
|
|||
code = "https://github.com/pragdave/earmark/"
|
||||
{result, [], []} = Utils.format_input(code, "text/markdown")
|
||||
assert result == ~s[<p><a href="#{code}">#{code}</a></p>]
|
||||
|
||||
code = "https://github.com/~foo/bar"
|
||||
{result, [], []} = Utils.format_input(code, "text/markdown")
|
||||
assert result == ~s[<p><a href="#{code}">#{code}</a></p>]
|
||||
end
|
||||
|
||||
test "link with local mention" do
|
||||
|
|
@ -196,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's up?</p>]
|
||||
end
|
||||
|
||||
test "remote mentions" do
|
||||
|
|
@ -207,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's up?</p>]
|
||||
end
|
||||
|
||||
test "raw HTML" do
|
||||
|
|
@ -225,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't are you quoting?</p></blockquote>"
|
||||
end
|
||||
|
||||
test "code" do
|
||||
|
|
@ -582,41 +586,61 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "attachments_from_ids_descs/2" do
|
||||
describe "attachments_from_ids_descs/3" do
|
||||
test "returns [] when attachment ids is empty" do
|
||||
assert Utils.attachments_from_ids_descs([], "{}") == []
|
||||
assert Utils.attachments_from_ids_descs([], "{}", nil) == []
|
||||
end
|
||||
|
||||
test "returns list attachments with desc" do
|
||||
object = insert(:note)
|
||||
user = insert(:user)
|
||||
object = insert(:attachment, %{user: user})
|
||||
desc = Jason.encode!(%{object.id => "test-desc"})
|
||||
|
||||
assert Utils.attachments_from_ids_descs(["#{object.id}", "34"], desc) == [
|
||||
assert Utils.attachments_from_ids_descs(["#{object.id}", "34"], desc, user) == [
|
||||
Map.merge(object.data, %{"name" => "test-desc"})
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
describe "attachments_from_ids/1" do
|
||||
describe "attachments_from_ids/2" do
|
||||
test "returns attachments with descs" do
|
||||
object = insert(:note)
|
||||
user = insert(:user)
|
||||
object = insert(:attachment, %{user: user})
|
||||
desc = Jason.encode!(%{object.id => "test-desc"})
|
||||
|
||||
assert Utils.attachments_from_ids(%{
|
||||
media_ids: ["#{object.id}"],
|
||||
descriptions: desc
|
||||
}) == [
|
||||
assert Utils.attachments_from_ids(
|
||||
%{
|
||||
media_ids: ["#{object.id}"],
|
||||
descriptions: desc
|
||||
},
|
||||
user
|
||||
) == [
|
||||
Map.merge(object.data, %{"name" => "test-desc"})
|
||||
]
|
||||
end
|
||||
|
||||
test "returns attachments without descs" do
|
||||
object = insert(:note)
|
||||
assert Utils.attachments_from_ids(%{media_ids: ["#{object.id}"]}) == [object.data]
|
||||
user = insert(:user)
|
||||
object = insert(:attachment, %{user: user})
|
||||
assert Utils.attachments_from_ids(%{media_ids: ["#{object.id}"]}, user) == [object.data]
|
||||
end
|
||||
|
||||
test "returns [] when not pass media_ids" do
|
||||
assert Utils.attachments_from_ids(%{}) == []
|
||||
assert Utils.attachments_from_ids(%{}, nil) == []
|
||||
end
|
||||
|
||||
test "returns [] when media_ids not belong to current user" do
|
||||
user = insert(:user)
|
||||
user2 = insert(:user)
|
||||
|
||||
object = insert(:attachment, %{user: user})
|
||||
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
defmodule Pleroma.Web.CommonAPITest do
|
||||
use Oban.Testing, repo: Pleroma.Repo
|
||||
use Pleroma.DataCase
|
||||
use Pleroma.DataCase, async: false
|
||||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Chat
|
||||
|
|
@ -279,6 +279,24 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
assert {:reject, "[KeywordPolicy] Matches with rejected keyword"} ==
|
||||
CommonAPI.post_chat_message(author, recipient, "GNO/Linux")
|
||||
end
|
||||
|
||||
test "it reject messages with attachments not belonging to user" do
|
||||
author = insert(:user)
|
||||
not_author = insert(:user)
|
||||
recipient = author
|
||||
|
||||
attachment = insert(:attachment, %{user: not_author})
|
||||
|
||||
{:error, message} =
|
||||
CommonAPI.post_chat_message(
|
||||
author,
|
||||
recipient,
|
||||
"123",
|
||||
media_id: attachment.id
|
||||
)
|
||||
|
||||
assert message == :forbidden
|
||||
end
|
||||
end
|
||||
|
||||
describe "unblocking" do
|
||||
|
|
@ -331,7 +349,7 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
refute Activity.get_by_id(post.id)
|
||||
end
|
||||
|
||||
test "it does not allow a user to delete their posts" do
|
||||
test "it does not allow a user to delete posts from another user" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
|
|
@ -341,7 +359,8 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
assert Activity.get_by_id(post.id)
|
||||
end
|
||||
|
||||
test "it allows moderators to delete other user's posts" do
|
||||
test "it allows privileged users to delete other user's posts" do
|
||||
clear_config([:instance, :moderator_privileges], [:messages_delete])
|
||||
user = insert(:user)
|
||||
moderator = insert(:user, is_moderator: true)
|
||||
|
||||
|
|
@ -353,19 +372,20 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
refute Activity.get_by_id(post.id)
|
||||
end
|
||||
|
||||
test "it allows admins to delete other user's posts" do
|
||||
test "it doesn't allow unprivileged mods or admins to delete other user's posts" do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
clear_config([:instance, :moderator_privileges], [])
|
||||
user = insert(:user)
|
||||
moderator = insert(:user, is_admin: true)
|
||||
moderator = insert(:user, is_moderator: true, is_admin: true)
|
||||
|
||||
{:ok, post} = CommonAPI.post(user, %{status: "namu amida butsu"})
|
||||
|
||||
assert {:ok, delete} = CommonAPI.delete(post.id, moderator)
|
||||
assert delete.local
|
||||
|
||||
refute Activity.get_by_id(post.id)
|
||||
assert {:error, "Could not delete"} = CommonAPI.delete(post.id, moderator)
|
||||
assert Activity.get_by_id(post.id)
|
||||
end
|
||||
|
||||
test "superusers deleting non-local posts won't federate the delete" do
|
||||
test "privileged users deleting non-local posts won't federate the delete" do
|
||||
clear_config([:instance, :admin_privileges], [:messages_delete])
|
||||
# This is the user of the ingested activity
|
||||
_user =
|
||||
insert(:user,
|
||||
|
|
@ -374,7 +394,7 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
last_refreshed_at: NaiveDateTime.utc_now()
|
||||
)
|
||||
|
||||
moderator = insert(:user, is_admin: true)
|
||||
admin = insert(:user, is_admin: true)
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|
|
@ -384,13 +404,27 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
|
||||
with_mock Pleroma.Web.Federator,
|
||||
publish: fn _ -> nil end do
|
||||
assert {:ok, delete} = CommonAPI.delete(post.id, moderator)
|
||||
assert {:ok, delete} = CommonAPI.delete(post.id, admin)
|
||||
assert delete.local
|
||||
refute called(Pleroma.Web.Federator.publish(:_))
|
||||
end
|
||||
|
||||
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
|
||||
|
|
@ -516,6 +550,36 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
assert Object.tags(object) == ["2hu"]
|
||||
end
|
||||
|
||||
test "zwnj is treated as word character" do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "#ساٴينس"})
|
||||
|
||||
object = Object.normalize(activity, fetch: false)
|
||||
|
||||
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"
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: text})
|
||||
|
||||
object = Object.normalize(activity, fetch: false)
|
||||
|
||||
assert object.data["content"] == "<a href=\"#{text}\" rel=\"ugc\">#{text}</a>"
|
||||
end
|
||||
|
||||
test "it adds emoji in the object" do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: ":firefox:"})
|
||||
|
|
@ -732,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
|
||||
|
|
@ -1307,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)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
@ -133,7 +131,7 @@ defmodule Pleroma.Web.FederatorTest do
|
|||
assert {:ok, _activity} = ObanHelpers.perform(job)
|
||||
|
||||
assert {:ok, job} = Federator.incoming_ap_doc(params)
|
||||
assert {:error, :already_present} = ObanHelpers.perform(job)
|
||||
assert {:cancel, :already_present} = ObanHelpers.perform(job)
|
||||
end
|
||||
|
||||
test "rejects incoming AP docs with incorrect origin" do
|
||||
|
|
|
|||
|
|
@ -57,9 +57,23 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|
|||
)
|
||||
|
||||
note_activity2 = insert(:note_activity, note: note2)
|
||||
|
||||
note3 =
|
||||
insert(:note,
|
||||
user: user,
|
||||
data: %{
|
||||
"content" => "This note tests whether HTML entities are truncated properly",
|
||||
"summary" => "Won't, didn't fail",
|
||||
"inReplyTo" => note_activity2.id
|
||||
}
|
||||
)
|
||||
|
||||
_note_activity3 = insert(:note_activity, note: note3)
|
||||
object = Object.normalize(note_activity, fetch: false)
|
||||
|
||||
[user: user, object: object, max_id: note_activity2.id]
|
||||
encoded_title = FeedView.activity_title(note3.data)
|
||||
|
||||
[user: user, object: object, max_id: note_activity2.id, encoded_title: encoded_title]
|
||||
end
|
||||
|
||||
test "gets an atom feed", %{conn: conn, user: user, object: object, max_id: max_id} do
|
||||
|
|
@ -74,7 +88,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|
|||
|> SweetXml.parse()
|
||||
|> SweetXml.xpath(~x"//entry/title/text()"l)
|
||||
|
||||
assert activity_titles == ['2hu', '2hu & as']
|
||||
assert activity_titles == ['Won\'t, didn\'...', '2hu', '2hu & as']
|
||||
assert resp =~ FeedView.escape(object.data["content"])
|
||||
assert resp =~ FeedView.escape(object.data["summary"])
|
||||
assert resp =~ FeedView.escape(object.data["context"])
|
||||
|
|
@ -105,7 +119,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|
|||
|> SweetXml.parse()
|
||||
|> SweetXml.xpath(~x"//item/title/text()"l)
|
||||
|
||||
assert activity_titles == ['2hu', '2hu & as']
|
||||
assert activity_titles == ['Won\'t, didn\'...', '2hu', '2hu & as']
|
||||
assert resp =~ FeedView.escape(object.data["content"])
|
||||
assert resp =~ FeedView.escape(object.data["summary"])
|
||||
assert resp =~ FeedView.escape(object.data["context"])
|
||||
|
|
@ -176,6 +190,30 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|
|||
|> get("/users/#{user.nickname}/feed.rss")
|
||||
|> response(200)
|
||||
end
|
||||
|
||||
test "does not mangle HTML entities midway", %{
|
||||
conn: conn,
|
||||
user: user,
|
||||
object: object,
|
||||
encoded_title: encoded_title
|
||||
} do
|
||||
resp =
|
||||
conn
|
||||
|> put_req_header("accept", "application/atom+xml")
|
||||
|> get(user_feed_path(conn, :feed, user.nickname))
|
||||
|> response(200)
|
||||
|
||||
activity_titles =
|
||||
resp
|
||||
|> SweetXml.parse()
|
||||
|> SweetXml.xpath(~x"//entry/title/text()"l)
|
||||
|
||||
assert activity_titles == ['Won\'t, didn\'...', '2hu', '2hu & as']
|
||||
assert resp =~ FeedView.escape(object.data["content"])
|
||||
assert resp =~ FeedView.escape(object.data["summary"])
|
||||
assert resp =~ FeedView.escape(object.data["context"])
|
||||
assert resp =~ encoded_title
|
||||
end
|
||||
end
|
||||
|
||||
# Note: see ActivityPubControllerTest for JSON format tests
|
||||
|
|
|
|||
|
|
@ -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"})
|
||||
|
|
|
|||
|
|
@ -92,4 +92,18 @@ defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do
|
|||
|
||||
assert ["peer1.com", "peer2.com"] == Enum.sort(result)
|
||||
end
|
||||
|
||||
test "instance languages", %{conn: conn} do
|
||||
assert %{"languages" => ["en"]} =
|
||||
conn
|
||||
|> get("/api/v1/instance")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
clear_config([:instance, :languages], ["aa", "bb"])
|
||||
|
||||
assert %{"languages" => ["aa", "bb"]} =
|
||||
conn
|
||||
|> get("/api/v1/instance")
|
||||
|> json_response_and_validate_schema(200)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -122,6 +122,23 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
|
|||
|
||||
assert :ok == File.rm(Path.absname("test/tmp/large_binary.data"))
|
||||
end
|
||||
|
||||
test "Do not allow nested filename", %{conn: conn, image: image} do
|
||||
image = %Plug.Upload{
|
||||
image
|
||||
| filename: "../../../../../nested/file.jpg"
|
||||
}
|
||||
|
||||
desc = "Description of the image"
|
||||
|
||||
media =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/v1/media", %{"file" => image, "description" => desc})
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
refute Regex.match?(~r"/nested/", media["url"])
|
||||
end
|
||||
end
|
||||
|
||||
describe "Update media description" do
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
|
||||
use Pleroma.Web.ConnCase
|
||||
use Pleroma.Web.ConnCase, async: false
|
||||
|
||||
alias Pleroma.Notification
|
||||
alias Pleroma.Repo
|
||||
|
|
@ -74,12 +74,15 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
|
|||
end
|
||||
|
||||
test "by default, does not contain pleroma:report" do
|
||||
%{user: user, conn: conn} = oauth_access(["read:notifications"])
|
||||
clear_config([:instance, :moderator_privileges], [:reports_manage_reports])
|
||||
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
third_user = insert(:user)
|
||||
|
||||
user
|
||||
|> User.admin_api_update(%{is_moderator: true})
|
||||
{:ok, user} = user |> User.admin_api_update(%{is_moderator: true})
|
||||
|
||||
%{conn: conn} = oauth_access(["read:notifications"], user: user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(other_user, %{status: "hey"})
|
||||
|
||||
|
|
@ -101,6 +104,39 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
|
|||
assert [_] = result
|
||||
end
|
||||
|
||||
test "Pleroma:report is hidden for non-privileged users" do
|
||||
clear_config([:instance, :moderator_privileges], [:reports_manage_reports])
|
||||
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
third_user = insert(:user)
|
||||
|
||||
{:ok, user} = user |> User.admin_api_update(%{is_moderator: true})
|
||||
|
||||
%{conn: conn} = oauth_access(["read:notifications"], user: user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(other_user, %{status: "hey"})
|
||||
|
||||
{:ok, _report} =
|
||||
CommonAPI.report(third_user, %{account_id: other_user.id, status_ids: [activity.id]})
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/notifications?include_types[]=pleroma:report")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [_] = result
|
||||
|
||||
clear_config([:instance, :moderator_privileges], [])
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/notifications?include_types[]=pleroma:report")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [] == result
|
||||
end
|
||||
|
||||
test "excludes mentions from blockers when blockers_visible is false" do
|
||||
clear_config([:activitypub, :blockers_visible], false)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
||||
use Pleroma.Web.ConnCase
|
||||
use Pleroma.Web.ConnCase, async: false
|
||||
use Oban.Testing, repo: Pleroma.Repo
|
||||
|
||||
alias Pleroma.Activity
|
||||
|
|
@ -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"])
|
||||
|
|
@ -971,9 +1289,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
assert Activity.get_by_id(activity.id) == activity
|
||||
end
|
||||
|
||||
test "when you're an admin", %{conn: conn} do
|
||||
test "when you're privileged to", %{conn: conn} do
|
||||
clear_config([:instance, :moderator_privileges], [:messages_delete])
|
||||
activity = insert(:note_activity)
|
||||
user = insert(:user, is_admin: true)
|
||||
user = insert(:user, is_moderator: true)
|
||||
|
||||
res_conn =
|
||||
conn
|
||||
|
|
@ -989,8 +1308,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
refute Activity.get_by_id(activity.id)
|
||||
end
|
||||
|
||||
test "when you're a moderator", %{conn: conn} do
|
||||
activity = insert(:note_activity)
|
||||
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 =
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -383,6 +421,34 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|
|||
assert :ok == File.rm(Path.absname("test/tmp/large_binary.data"))
|
||||
end
|
||||
|
||||
test "Strip / from upload files", %{user: user, conn: conn} do
|
||||
new_image = %Plug.Upload{
|
||||
content_type: "image/jpeg",
|
||||
path: Path.absname("test/fixtures/image.jpg"),
|
||||
filename: "../../../../nested/an_image.jpg"
|
||||
}
|
||||
|
||||
assert user.avatar == %{}
|
||||
|
||||
res =
|
||||
patch(conn, "/api/v1/accounts/update_credentials", %{
|
||||
"avatar" => new_image,
|
||||
"header" => new_image,
|
||||
"pleroma_background_image" => new_image
|
||||
})
|
||||
|
||||
assert user_response = json_response_and_validate_schema(res, 200)
|
||||
assert user_response["avatar"]
|
||||
assert user_response["header"]
|
||||
assert user_response["pleroma"]["background_image"]
|
||||
refute Regex.match?(~r"/nested/", user_response["avatar"])
|
||||
refute Regex.match?(~r"/nested/", user_response["header"])
|
||||
refute Regex.match?(~r"/nested/", user_response["pleroma"]["background_image"])
|
||||
|
||||
user = User.get_by_id(user.id)
|
||||
refute user.avatar == %{}
|
||||
end
|
||||
|
||||
test "requires 'write:accounts' permission" do
|
||||
token1 = insert(:oauth_token, scopes: ["read"])
|
||||
token2 = insert(:oauth_token, scopes: ["write", "follow"])
|
||||
|
|
@ -565,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)
|
||||
|
||||
|
|
@ -584,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
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
||||
use Pleroma.DataCase
|
||||
use Pleroma.DataCase, async: false
|
||||
|
||||
alias Pleroma.User
|
||||
alias Pleroma.UserRelationship
|
||||
|
|
@ -84,6 +84,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
|||
tags: [],
|
||||
is_admin: false,
|
||||
is_moderator: false,
|
||||
privileges: [],
|
||||
is_suggested: false,
|
||||
hide_favorites: true,
|
||||
hide_followers: false,
|
||||
|
|
@ -99,6 +100,147 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
|||
assert expected == AccountView.render("show.json", %{user: user, skip_visibility_check: true})
|
||||
end
|
||||
|
||||
describe "roles and privileges" do
|
||||
setup do
|
||||
clear_config([:instance, :moderator_privileges], [:cofe, :only_moderator])
|
||||
clear_config([:instance, :admin_privileges], [:cofe, :only_admin])
|
||||
|
||||
%{
|
||||
user: insert(:user),
|
||||
moderator: insert(:user, is_moderator: true),
|
||||
admin: insert(:user, is_admin: true),
|
||||
moderator_admin: insert(:user, is_moderator: true, is_admin: true),
|
||||
user_no_show_roles: insert(:user, show_role: false),
|
||||
moderator_admin_no_show_roles:
|
||||
insert(:user, is_moderator: true, is_admin: true, show_role: false)
|
||||
}
|
||||
end
|
||||
|
||||
test "shows roles and privileges when show_role: true", %{
|
||||
user: user,
|
||||
moderator: moderator,
|
||||
admin: admin,
|
||||
moderator_admin: moderator_admin,
|
||||
user_no_show_roles: user_no_show_roles,
|
||||
moderator_admin_no_show_roles: moderator_admin_no_show_roles
|
||||
} do
|
||||
assert %{pleroma: %{is_moderator: false, is_admin: false}} =
|
||||
AccountView.render("show.json", %{user: user, skip_visibility_check: true})
|
||||
|
||||
assert [] ==
|
||||
AccountView.render("show.json", %{user: user, skip_visibility_check: true})[
|
||||
:pleroma
|
||||
][:privileges]
|
||||
|> Enum.sort()
|
||||
|
||||
assert %{pleroma: %{is_moderator: true, is_admin: false}} =
|
||||
AccountView.render("show.json", %{user: moderator, skip_visibility_check: true})
|
||||
|
||||
assert [:cofe, :only_moderator] ==
|
||||
AccountView.render("show.json", %{user: moderator, skip_visibility_check: true})[
|
||||
:pleroma
|
||||
][:privileges]
|
||||
|> Enum.sort()
|
||||
|
||||
assert %{pleroma: %{is_moderator: false, is_admin: true}} =
|
||||
AccountView.render("show.json", %{user: admin, skip_visibility_check: true})
|
||||
|
||||
assert [:cofe, :only_admin] ==
|
||||
AccountView.render("show.json", %{user: admin, skip_visibility_check: true})[
|
||||
:pleroma
|
||||
][:privileges]
|
||||
|> Enum.sort()
|
||||
|
||||
assert %{pleroma: %{is_moderator: true, is_admin: true}} =
|
||||
AccountView.render("show.json", %{
|
||||
user: moderator_admin,
|
||||
skip_visibility_check: true
|
||||
})
|
||||
|
||||
assert [:cofe, :only_admin, :only_moderator] ==
|
||||
AccountView.render("show.json", %{
|
||||
user: moderator_admin,
|
||||
skip_visibility_check: true
|
||||
})[:pleroma][:privileges]
|
||||
|> Enum.sort()
|
||||
|
||||
refute match?(
|
||||
%{pleroma: %{is_moderator: _}},
|
||||
AccountView.render("show.json", %{
|
||||
user: user_no_show_roles,
|
||||
skip_visibility_check: true
|
||||
})
|
||||
)
|
||||
|
||||
refute match?(
|
||||
%{pleroma: %{is_admin: _}},
|
||||
AccountView.render("show.json", %{
|
||||
user: user_no_show_roles,
|
||||
skip_visibility_check: true
|
||||
})
|
||||
)
|
||||
|
||||
refute match?(
|
||||
%{pleroma: %{privileges: _}},
|
||||
AccountView.render("show.json", %{
|
||||
user: user_no_show_roles,
|
||||
skip_visibility_check: true
|
||||
})
|
||||
)
|
||||
|
||||
refute match?(
|
||||
%{pleroma: %{is_moderator: _}},
|
||||
AccountView.render("show.json", %{
|
||||
user: moderator_admin_no_show_roles,
|
||||
skip_visibility_check: true
|
||||
})
|
||||
)
|
||||
|
||||
refute match?(
|
||||
%{pleroma: %{is_admin: _}},
|
||||
AccountView.render("show.json", %{
|
||||
user: moderator_admin_no_show_roles,
|
||||
skip_visibility_check: true
|
||||
})
|
||||
)
|
||||
|
||||
refute match?(
|
||||
%{pleroma: %{privileges: _}},
|
||||
AccountView.render("show.json", %{
|
||||
user: moderator_admin_no_show_roles,
|
||||
skip_visibility_check: true
|
||||
})
|
||||
)
|
||||
end
|
||||
|
||||
test "shows roles and privileges when viewing own account, even when show_role: false", %{
|
||||
user_no_show_roles: user_no_show_roles,
|
||||
moderator_admin_no_show_roles: moderator_admin_no_show_roles
|
||||
} do
|
||||
assert %{pleroma: %{is_moderator: false, is_admin: false, privileges: []}} =
|
||||
AccountView.render("show.json", %{
|
||||
user: user_no_show_roles,
|
||||
skip_visibility_check: true,
|
||||
for: user_no_show_roles
|
||||
})
|
||||
|
||||
assert %{
|
||||
pleroma: %{
|
||||
is_moderator: true,
|
||||
is_admin: true,
|
||||
privileges: privileges
|
||||
}
|
||||
} =
|
||||
AccountView.render("show.json", %{
|
||||
user: moderator_admin_no_show_roles,
|
||||
skip_visibility_check: true,
|
||||
for: moderator_admin_no_show_roles
|
||||
})
|
||||
|
||||
assert [:cofe, :only_admin, :only_moderator] == privileges |> Enum.sort()
|
||||
end
|
||||
end
|
||||
|
||||
describe "favicon" do
|
||||
setup do
|
||||
[user: insert(:user)]
|
||||
|
|
@ -186,6 +328,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
|||
tags: [],
|
||||
is_admin: false,
|
||||
is_moderator: false,
|
||||
privileges: [],
|
||||
is_suggested: false,
|
||||
hide_favorites: true,
|
||||
hide_followers: false,
|
||||
|
|
@ -214,8 +357,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
|||
assert represented.url == "https://channels.tests.funkwhale.audio/channels/compositions"
|
||||
end
|
||||
|
||||
test "Represent a deactivated user for an admin" do
|
||||
admin = insert(:user, is_admin: true)
|
||||
test "Represent a deactivated user for a privileged user" do
|
||||
clear_config([:instance, :moderator_privileges], [:users_manage_activation_state])
|
||||
|
||||
admin = insert(:user, is_moderator: true)
|
||||
deactivated_user = insert(:user, is_active: false)
|
||||
represented = AccountView.render("show.json", %{user: deactivated_user, for: admin})
|
||||
assert represented[:pleroma][:deactivated] == true
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
|
||||
use Pleroma.DataCase
|
||||
use Pleroma.DataCase, async: false
|
||||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Chat
|
||||
|
|
@ -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])
|
||||
|
|
@ -218,9 +258,11 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
|
|||
end
|
||||
|
||||
test "Report notification" do
|
||||
clear_config([:instance, :moderator_privileges], [:reports_manage_reports])
|
||||
|
||||
reporting_user = insert(:user)
|
||||
reported_user = insert(:user)
|
||||
{:ok, moderator_user} = insert(:user) |> User.admin_api_update(%{is_moderator: true})
|
||||
moderator_user = insert(:user, is_moderator: true)
|
||||
|
||||
{:ok, activity} = CommonAPI.report(reporting_user, %{account_id: reported_user.id})
|
||||
{:ok, [notification]} = Notification.create_notifications(activity)
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityViewTest do
|
|||
id: to_string(scheduled_activity.id),
|
||||
media_attachments:
|
||||
%{media_ids: [upload.id]}
|
||||
|> Utils.attachments_from_ids()
|
||||
|> Utils.attachments_from_ids(user)
|
||||
|> Enum.map(&StatusView.render("attachment.json", %{attachment: &1})),
|
||||
params: %{
|
||||
in_reply_to_id: to_string(activity.id),
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
use Pleroma.Web.ConnCase
|
||||
|
||||
import Mock
|
||||
import Mox
|
||||
|
||||
alias Pleroma.ReverseProxy.ClientMock
|
||||
alias Pleroma.Web.MediaProxy
|
||||
alias Plug.Conn
|
||||
|
||||
|
|
@ -74,6 +76,20 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
assert %Conn{status: 404, resp_body: "Not Found"} = get(conn, url)
|
||||
end
|
||||
end
|
||||
|
||||
test "it applies sandbox CSP to MediaProxy requests", %{conn: conn} do
|
||||
media_url = "https://lain.com/image.png"
|
||||
media_proxy_url = MediaProxy.encode_url(media_url)
|
||||
|
||||
ClientMock
|
||||
|> expect(:request, fn :get, ^media_url, _, _, _ ->
|
||||
{:ok, 200, [{"content-type", "image/png"}]}
|
||||
end)
|
||||
|
||||
%Conn{resp_headers: headers} = get(conn, media_proxy_url)
|
||||
|
||||
assert {"content-security-policy", "sandbox;"} in headers
|
||||
end
|
||||
end
|
||||
|
||||
describe "Media Preview Proxy" do
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"], []},
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ defmodule Pleroma.Web.Metadata.UtilsTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "scrub_html_and_truncate/2" do
|
||||
describe "scrub_html_and_truncate/3" do
|
||||
test "it returns text without encode HTML" do
|
||||
assert Utils.scrub_html_and_truncate("Pleroma's really cool!") == "Pleroma's really cool!"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.NodeInfoTest do
|
||||
use Pleroma.Web.ConnCase
|
||||
use Pleroma.Web.ConnCase, async: false
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
|
|
@ -40,6 +40,19 @@ defmodule Pleroma.Web.NodeInfoTest do
|
|||
assert admin.ap_id in result["metadata"]["staffAccounts"]
|
||||
end
|
||||
|
||||
test "nodeinfo shows roles and privileges", %{conn: conn} do
|
||||
clear_config([:instance, :moderator_privileges], [:cofe])
|
||||
clear_config([:instance, :admin_privileges], [:suya, :cofe])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> get("/nodeinfo/2.1.json")
|
||||
|
||||
assert result = json_response(conn, 200)
|
||||
|
||||
assert %{"admin" => ["suya", "cofe"], "moderator" => ["cofe"]} == result["metadata"]["roles"]
|
||||
end
|
||||
|
||||
test "nodeinfo shows restricted nicknames", %{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.PleromaAPI.EmojiFileControllerTest do
|
||||
use Pleroma.Web.ConnCase
|
||||
use Pleroma.Web.ConnCase, async: false
|
||||
|
||||
import Mock
|
||||
import Tesla.Mock
|
||||
|
|
@ -30,6 +30,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiFileControllerTest do
|
|||
|
||||
describe "POST/PATCH/DELETE /api/pleroma/emoji/packs/files?name=:name" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:emoji_manage_emoji])
|
||||
pack_file = "#{@emoji_path}/test_pack/pack.json"
|
||||
original_content = File.read!(pack_file)
|
||||
|
||||
|
|
@ -377,5 +378,32 @@ defmodule Pleroma.Web.PleromaAPI.EmojiFileControllerTest do
|
|||
})
|
||||
|> json_response_and_validate_schema(:bad_request)
|
||||
end
|
||||
|
||||
test "it requires privileged role :emoji_manage_emoji", %{admin_conn: admin_conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
assert admin_conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/pleroma/emoji/packs/files?name=test_pack", %{
|
||||
file: %Plug.Upload{
|
||||
filename: "shortcode.png",
|
||||
path: "#{Pleroma.Config.get([:instance, :static_dir])}/add/shortcode.png"
|
||||
}
|
||||
})
|
||||
|> json_response(:forbidden)
|
||||
|
||||
assert admin_conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> patch("/api/pleroma/emoji/packs/files?name=test_pack", %{
|
||||
shortcode: "blank",
|
||||
new_filename: "dir_2/blank_3.png"
|
||||
})
|
||||
|> json_response(:forbidden)
|
||||
|
||||
assert admin_conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> delete("/api/pleroma/emoji/packs/files?name=test_pack&shortcode=blank3")
|
||||
|> json_response(:forbidden)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -99,6 +99,10 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
|
|||
end
|
||||
|
||||
describe "GET /api/pleroma/emoji/packs/remote" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:emoji_manage_emoji])
|
||||
end
|
||||
|
||||
test "shareable instance", %{admin_conn: admin_conn, conn: conn} do
|
||||
resp =
|
||||
conn
|
||||
|
|
@ -136,6 +140,14 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
|
|||
"error" => "The requested instance does not support sharing emoji packs"
|
||||
}
|
||||
end
|
||||
|
||||
test "it requires privileged role :emoji_manage_emoji", %{admin_conn: admin_conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
assert admin_conn
|
||||
|> get("/api/pleroma/emoji/packs/remote?url=https://example.com")
|
||||
|> json_response(:forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /api/pleroma/emoji/packs/archive?name=:name" do
|
||||
|
|
@ -170,6 +182,10 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
|
|||
end
|
||||
|
||||
describe "POST /api/pleroma/emoji/packs/download" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:emoji_manage_emoji])
|
||||
end
|
||||
|
||||
test "shared pack from remote and non shared from fallback-src", %{
|
||||
admin_conn: admin_conn,
|
||||
conn: conn
|
||||
|
|
@ -344,10 +360,24 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
|
|||
"The pack was not set as shared and there is no fallback src to download from"
|
||||
}
|
||||
end
|
||||
|
||||
test "it requires privileged role :emoji_manage_emoji", %{admin_conn: conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
assert conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/pleroma/emoji/packs/download", %{
|
||||
url: "https://example.com",
|
||||
name: "test_pack",
|
||||
as: "test_pack2"
|
||||
})
|
||||
|> json_response(:forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "PATCH/update /api/pleroma/emoji/pack?name=:name" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:emoji_manage_emoji])
|
||||
pack_file = "#{@emoji_path}/test_pack/pack.json"
|
||||
original_content = File.read!(pack_file)
|
||||
|
||||
|
|
@ -435,9 +465,25 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
|
|||
"error" => "The fallback archive does not have all files specified in pack.json"
|
||||
}
|
||||
end
|
||||
|
||||
test "it requires privileged role :emoji_manage_emoji", %{
|
||||
admin_conn: conn,
|
||||
new_data: new_data
|
||||
} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
assert conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> patch("/api/pleroma/emoji/pack?name=test_pack", %{metadata: new_data})
|
||||
|> json_response(:forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST/DELETE /api/pleroma/emoji/pack?name=:name" do
|
||||
setup do
|
||||
clear_config([:instance, :admin_privileges], [:emoji_manage_emoji])
|
||||
end
|
||||
|
||||
test "returns an error on creates pack when file system not writable", %{
|
||||
admin_conn: admin_conn
|
||||
} do
|
||||
|
|
@ -520,6 +566,18 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
|
|||
"error" => "pack name cannot be empty"
|
||||
}
|
||||
end
|
||||
|
||||
test "it requires privileged role :emoji_manage_emoji", %{admin_conn: admin_conn} do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
assert admin_conn
|
||||
|> post("/api/pleroma/emoji/pack?name= ")
|
||||
|> json_response(:forbidden)
|
||||
|
||||
assert admin_conn
|
||||
|> delete("/api/pleroma/emoji/pack?name= ")
|
||||
|> json_response(:forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
test "deleting nonexisting pack", %{admin_conn: admin_conn} do
|
||||
|
|
@ -578,6 +636,12 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
|
|||
"blank2" => "blank.png",
|
||||
"foo" => "blank.png"
|
||||
}
|
||||
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
|
||||
assert admin_conn
|
||||
|> get("/api/pleroma/emoji/packs/import")
|
||||
|> json_response(:forbidden)
|
||||
end
|
||||
|
||||
describe "GET /api/pleroma/emoji/pack?name=:name" do
|
||||
|
|
|
|||
|
|
@ -17,23 +17,113 @@ 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" => [["👍", [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/☕")
|
||||
|> put("/api/v1/pleroma/statuses/#{activity.id}/reactions/\u26A0")
|
||||
|> 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" => "👍",
|
||||
"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/:dinosaur:")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert %{"id" => id} = result
|
||||
assert to_string(activity.id) == id
|
||||
|
||||
assert result["pleroma"]["emoji_reactions"] == [
|
||||
%{
|
||||
"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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatMessageReferenceViewTest do
|
|||
filename: "an_image.jpg"
|
||||
}
|
||||
|
||||
{:ok, upload} = ActivityPub.upload(file, actor: user.ap_id)
|
||||
{:ok, upload} = ActivityPub.upload(file, actor: recipient.ap_id)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post_chat_message(user, recipient, "kippis :firefox:", idempotency_key: "123")
|
||||
|
|
|
|||
|
|
@ -70,28 +70,6 @@ defmodule Pleroma.Web.Plugs.AuthenticationPlugTest do
|
|||
assert "$pbkdf2" <> _ = user.password_hash
|
||||
end
|
||||
|
||||
@tag :skip_on_mac
|
||||
test "with a crypt hash, it updates to a pkbdf2 hash", %{conn: conn} do
|
||||
user =
|
||||
insert(:user,
|
||||
password_hash:
|
||||
"$6$9psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1"
|
||||
)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:auth_user, user)
|
||||
|> assign(:auth_credentials, %{password: "password"})
|
||||
|> AuthenticationPlug.call(%{})
|
||||
|
||||
assert conn.assigns.user.id == conn.assigns.auth_user.id
|
||||
assert conn.assigns.token == nil
|
||||
assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
|
||||
|
||||
user = User.get_by_id(user.id)
|
||||
assert "$pbkdf2" <> _ = user.password_hash
|
||||
end
|
||||
|
||||
describe "checkpw/2" do
|
||||
test "check pbkdf2 hash" do
|
||||
hash =
|
||||
|
|
@ -101,14 +79,6 @@ defmodule Pleroma.Web.Plugs.AuthenticationPlugTest do
|
|||
refute AuthenticationPlug.checkpw("test-password1", hash)
|
||||
end
|
||||
|
||||
@tag :skip_on_mac
|
||||
test "check sha512-crypt hash" do
|
||||
hash =
|
||||
"$6$9psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1"
|
||||
|
||||
assert AuthenticationPlug.checkpw("password", hash)
|
||||
end
|
||||
|
||||
test "check bcrypt hash" do
|
||||
hash = "$2a$10$uyhC/R/zoE1ndwwCtMusK.TLVzkQ/Ugsbqp3uXI.CTTz0gBw.24jS"
|
||||
|
||||
|
|
|
|||
96
test/pleroma/web/plugs/ensure_privileged_plug_test.exs
Normal file
96
test/pleroma/web/plugs/ensure_privileged_plug_test.exs
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.Plugs.EnsurePrivilegedPlugTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
|
||||
alias Pleroma.Web.Plugs.EnsurePrivilegedPlug
|
||||
import Pleroma.Factory
|
||||
|
||||
test "denies a user that isn't moderator or admin" do
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
user = insert(:user)
|
||||
|
||||
conn =
|
||||
build_conn()
|
||||
|> assign(:user, user)
|
||||
|> EnsurePrivilegedPlug.call(:cofe)
|
||||
|
||||
assert conn.status == 403
|
||||
end
|
||||
|
||||
test "accepts an admin that is privileged" do
|
||||
clear_config([:instance, :admin_privileges], [:cofe])
|
||||
user = insert(:user, is_admin: true)
|
||||
conn = assign(build_conn(), :user, user)
|
||||
|
||||
ret_conn = EnsurePrivilegedPlug.call(conn, :cofe)
|
||||
|
||||
assert conn == ret_conn
|
||||
end
|
||||
|
||||
test "denies an admin that isn't privileged" do
|
||||
clear_config([:instance, :admin_privileges], [:suya])
|
||||
user = insert(:user, is_admin: true)
|
||||
|
||||
conn =
|
||||
build_conn()
|
||||
|> assign(:user, user)
|
||||
|> EnsurePrivilegedPlug.call(:cofe)
|
||||
|
||||
assert conn.status == 403
|
||||
end
|
||||
|
||||
test "accepts a moderator that is privileged" do
|
||||
clear_config([:instance, :moderator_privileges], [:cofe])
|
||||
user = insert(:user, is_moderator: true)
|
||||
conn = assign(build_conn(), :user, user)
|
||||
|
||||
ret_conn = EnsurePrivilegedPlug.call(conn, :cofe)
|
||||
|
||||
assert conn == ret_conn
|
||||
end
|
||||
|
||||
test "denies a moderator that isn't privileged" do
|
||||
clear_config([:instance, :moderator_privileges], [:suya])
|
||||
user = insert(:user, is_moderator: true)
|
||||
|
||||
conn =
|
||||
build_conn()
|
||||
|> assign(:user, user)
|
||||
|> EnsurePrivilegedPlug.call(:cofe)
|
||||
|
||||
assert conn.status == 403
|
||||
end
|
||||
|
||||
test "accepts for a privileged role even if other role isn't privileged" do
|
||||
clear_config([:instance, :admin_privileges], [:cofe])
|
||||
clear_config([:instance, :moderator_privileges], [])
|
||||
user = insert(:user, is_admin: true, is_moderator: true)
|
||||
conn = assign(build_conn(), :user, user)
|
||||
|
||||
ret_conn = EnsurePrivilegedPlug.call(conn, :cofe)
|
||||
|
||||
# privileged through admin role
|
||||
assert conn == ret_conn
|
||||
|
||||
clear_config([:instance, :admin_privileges], [])
|
||||
clear_config([:instance, :moderator_privileges], [:cofe])
|
||||
user = insert(:user, is_admin: true, is_moderator: true)
|
||||
conn = assign(build_conn(), :user, user)
|
||||
|
||||
ret_conn = EnsurePrivilegedPlug.call(conn, :cofe)
|
||||
|
||||
# privileged through moderator role
|
||||
assert conn == ret_conn
|
||||
end
|
||||
|
||||
test "denies when no user is set" do
|
||||
conn =
|
||||
build_conn()
|
||||
|> EnsurePrivilegedPlug.call(:cofe)
|
||||
|
||||
assert conn.status == 403
|
||||
end
|
||||
end
|
||||
|
|
@ -1,60 +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.Web.Plugs.EnsureStaffPrivilegedPlugTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
|
||||
alias Pleroma.Web.Plugs.EnsureStaffPrivilegedPlug
|
||||
import Pleroma.Factory
|
||||
|
||||
test "accepts a user that is an admin" do
|
||||
user = insert(:user, is_admin: true)
|
||||
|
||||
conn = assign(build_conn(), :user, user)
|
||||
|
||||
ret_conn = EnsureStaffPrivilegedPlug.call(conn, %{})
|
||||
|
||||
assert conn == ret_conn
|
||||
end
|
||||
|
||||
test "accepts a user that is a moderator when :privileged_staff is enabled" do
|
||||
clear_config([:instance, :privileged_staff], true)
|
||||
user = insert(:user, is_moderator: true)
|
||||
|
||||
conn = assign(build_conn(), :user, user)
|
||||
|
||||
ret_conn = EnsureStaffPrivilegedPlug.call(conn, %{})
|
||||
|
||||
assert conn == ret_conn
|
||||
end
|
||||
|
||||
test "denies a user that is a moderator when :privileged_staff is disabled" do
|
||||
clear_config([:instance, :privileged_staff], false)
|
||||
user = insert(:user, is_moderator: true)
|
||||
|
||||
conn =
|
||||
build_conn()
|
||||
|> assign(:user, user)
|
||||
|> EnsureStaffPrivilegedPlug.call(%{})
|
||||
|
||||
assert conn.status == 403
|
||||
end
|
||||
|
||||
test "denies a user that isn't a staff member" do
|
||||
user = insert(:user)
|
||||
|
||||
conn =
|
||||
build_conn()
|
||||
|> assign(:user, user)
|
||||
|> EnsureStaffPrivilegedPlug.call(%{})
|
||||
|
||||
assert conn.status == 403
|
||||
end
|
||||
|
||||
test "denies when a user isn't set" do
|
||||
conn = EnsureStaffPrivilegedPlug.call(build_conn(), %{})
|
||||
|
||||
assert conn.status == 403
|
||||
end
|
||||
end
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
|
|||
}}
|
||||
end
|
||||
|
||||
test "parses OEmbed" do
|
||||
test "parses OEmbed and filters HTML tags" do
|
||||
assert Parser.parse("http://example.com/oembed") ==
|
||||
{:ok,
|
||||
%{
|
||||
|
|
@ -139,7 +139,7 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
|
|||
"flickr_type" => "photo",
|
||||
"height" => "768",
|
||||
"html" =>
|
||||
"<a data-flickr-embed=\"true\" href=\"https://www.flickr.com/photos/bees/2362225867/\" title=\"Bacon Lollys by \u202E\u202D\u202Cbees\u202C, on Flickr\"><img src=\"https://farm4.staticflickr.com/3040/2362225867_4a87ab8baf_b.jpg\" width=\"1024\" height=\"768\" alt=\"Bacon Lollys\"></a><script async src=\"https://embedr.flickr.com/assets/client-code.js\" charset=\"utf-8\"></script>",
|
||||
"<a href=\"https://www.flickr.com/photos/bees/2362225867/\" title=\"Bacon Lollys by \u202E\u202D\u202Cbees\u202C, on Flickr\"><img src=\"https://farm4.staticflickr.com/3040/2362225867_4a87ab8baf_b.jpg\" width=\"1024\" height=\"768\" alt=\"Bacon Lollys\"/></a>",
|
||||
"license" => "All Rights Reserved",
|
||||
"license_id" => 0,
|
||||
"provider_name" => "Flickr",
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -29,6 +33,26 @@ defmodule Pleroma.Web.StreamerTest do
|
|||
assert {:ok, "public:local:media"} = Streamer.get_topic("public:local:media", nil, nil)
|
||||
end
|
||||
|
||||
test "rejects local public streams if restricted_unauthenticated is on" do
|
||||
clear_config([:restrict_unauthenticated, :timelines, :local], true)
|
||||
|
||||
assert {:error, :unauthorized} = Streamer.get_topic("public:local", nil, nil)
|
||||
assert {:error, :unauthorized} = Streamer.get_topic("public:local:media", nil, nil)
|
||||
end
|
||||
|
||||
test "rejects remote public streams if restricted_unauthenticated is on" do
|
||||
clear_config([:restrict_unauthenticated, :timelines, :federated], true)
|
||||
|
||||
assert {:error, :unauthorized} = Streamer.get_topic("public", nil, nil)
|
||||
assert {:error, :unauthorized} = Streamer.get_topic("public:media", nil, nil)
|
||||
|
||||
assert {:error, :unauthorized} =
|
||||
Streamer.get_topic("public:remote", nil, nil, %{"instance" => "lain.com"})
|
||||
|
||||
assert {:error, :unauthorized} =
|
||||
Streamer.get_topic("public:remote:media", nil, nil, %{"instance" => "lain.com"})
|
||||
end
|
||||
|
||||
test "allows instance streams" do
|
||||
assert {:ok, "public:remote:lain.com"} =
|
||||
Streamer.get_topic("public:remote", nil, nil, %{"instance" => "lain.com"})
|
||||
|
|
@ -69,6 +93,63 @@ defmodule Pleroma.Web.StreamerTest do
|
|||
end
|
||||
end
|
||||
|
||||
test "allows local public streams if restricted_unauthenticated is on", %{
|
||||
user: user,
|
||||
token: oauth_token
|
||||
} do
|
||||
clear_config([:restrict_unauthenticated, :timelines, :local], true)
|
||||
|
||||
%{token: read_notifications_token} = oauth_access(["read:notifications"], user: user)
|
||||
%{token: badly_scoped_token} = oauth_access(["irrelevant:scope"], user: user)
|
||||
|
||||
assert {:ok, "public:local"} = Streamer.get_topic("public:local", user, oauth_token)
|
||||
|
||||
assert {:ok, "public:local:media"} =
|
||||
Streamer.get_topic("public:local:media", user, oauth_token)
|
||||
|
||||
for token <- [read_notifications_token, badly_scoped_token] do
|
||||
assert {:error, :unauthorized} = Streamer.get_topic("public:local", user, token)
|
||||
|
||||
assert {:error, :unauthorized} = Streamer.get_topic("public:local:media", user, token)
|
||||
end
|
||||
end
|
||||
|
||||
test "allows remote public streams if restricted_unauthenticated is on", %{
|
||||
user: user,
|
||||
token: oauth_token
|
||||
} do
|
||||
clear_config([:restrict_unauthenticated, :timelines, :federated], true)
|
||||
|
||||
%{token: read_notifications_token} = oauth_access(["read:notifications"], user: user)
|
||||
%{token: badly_scoped_token} = oauth_access(["irrelevant:scope"], user: user)
|
||||
|
||||
assert {:ok, "public"} = Streamer.get_topic("public", user, oauth_token)
|
||||
assert {:ok, "public:media"} = Streamer.get_topic("public:media", user, oauth_token)
|
||||
|
||||
assert {:ok, "public:remote:lain.com"} =
|
||||
Streamer.get_topic("public:remote", user, oauth_token, %{"instance" => "lain.com"})
|
||||
|
||||
assert {:ok, "public:remote:media:lain.com"} =
|
||||
Streamer.get_topic("public:remote:media", user, oauth_token, %{
|
||||
"instance" => "lain.com"
|
||||
})
|
||||
|
||||
for token <- [read_notifications_token, badly_scoped_token] do
|
||||
assert {:error, :unauthorized} = Streamer.get_topic("public", user, token)
|
||||
assert {:error, :unauthorized} = Streamer.get_topic("public:media", user, token)
|
||||
|
||||
assert {:error, :unauthorized} =
|
||||
Streamer.get_topic("public:remote", user, token, %{
|
||||
"instance" => "lain.com"
|
||||
})
|
||||
|
||||
assert {:error, :unauthorized} =
|
||||
Streamer.get_topic("public:remote:media", user, token, %{
|
||||
"instance" => "lain.com"
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
test "allows user streams (with proper OAuth token scopes)", %{
|
||||
user: user,
|
||||
token: read_oauth_token
|
||||
|
|
@ -165,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
|
||||
|
||||
|
|
@ -176,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
|
||||
|
||||
|
|
@ -229,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
|
||||
|
||||
|
|
@ -241,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
|
||||
|
||||
|
|
@ -253,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
|
||||
|
||||
|
|
@ -274,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}
|
||||
|
|
@ -292,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}
|
||||
|
|
@ -313,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
|
||||
|
||||
|
|
@ -359,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
|
||||
|
|
@ -388,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
|
||||
|
|
@ -453,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
|
||||
|
||||
|
|
@ -464,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
|
||||
|
|
@ -477,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
|
||||
|
||||
|
|
@ -577,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
|
||||
|
||||
|
|
@ -599,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
|
||||
|
||||
|
|
@ -622,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
|
||||
|
|
@ -636,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
|
||||
|
||||
|
|
@ -653,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
|
||||
|
|
@ -724,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
|
||||
|
|
@ -742,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
|
||||
|
||||
|
|
@ -758,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
|
||||
|
||||
|
|
@ -774,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
|
||||
|
|
@ -789,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
|
||||
|
|
@ -831,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)
|
||||
|
||||
|
|
@ -866,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}
|
||||
|
|
@ -896,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.()
|
||||
|
|
|
|||
|
|
@ -180,5 +180,28 @@ defmodule Pleroma.Web.WebFingerTest do
|
|||
|
||||
{:ok, _data} = WebFinger.finger("pekorino@pawoo.net")
|
||||
end
|
||||
|
||||
test "refuses to process XML remote entities" do
|
||||
Tesla.Mock.mock(fn
|
||||
%{
|
||||
url: "https://pawoo.net/.well-known/webfinger?resource=acct:pekorino@pawoo.net"
|
||||
} ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/xml_external_entities.xml"),
|
||||
headers: [{"content-type", "application/xrd+xml"}]
|
||||
}}
|
||||
|
||||
%{url: "https://pawoo.net/.well-known/host-meta"} ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/tesla_mock/pawoo.net_host_meta")
|
||||
}}
|
||||
end)
|
||||
|
||||
assert :error = WebFinger.finger("pekorino@pawoo.net")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
15
test/pleroma/web/xml_test.exs
Normal file
15
test/pleroma/web/xml_test.exs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
defmodule Pleroma.Web.XMLTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
|
||||
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))
|
||||
end
|
||||
end
|
||||
|
|
@ -11,7 +11,7 @@ defmodule Pleroma.Workers.ReceiverWorkerTest do
|
|||
|
||||
alias Pleroma.Workers.ReceiverWorker
|
||||
|
||||
test "it ignores MRF reject" do
|
||||
test "it does not retry MRF reject" do
|
||||
params = insert(:note).data
|
||||
|
||||
with_mock Pleroma.Web.ActivityPub.Transmogrifier,
|
||||
|
|
@ -22,4 +22,31 @@ defmodule Pleroma.Workers.ReceiverWorkerTest do
|
|||
})
|
||||
end
|
||||
end
|
||||
|
||||
test "it does not retry ObjectValidator reject" do
|
||||
params =
|
||||
insert(:note_activity).data
|
||||
|> Map.put("id", Pleroma.Web.ActivityPub.Utils.generate_activity_id())
|
||||
|> Map.put("object", %{
|
||||
"type" => "Note",
|
||||
"id" => Pleroma.Web.ActivityPub.Utils.generate_object_id()
|
||||
})
|
||||
|
||||
with_mock Pleroma.Web.ActivityPub.ObjectValidator, [:passthrough],
|
||||
validate: fn _, _ -> {:error, %Ecto.Changeset{}} end do
|
||||
assert {:cancel, {:error, %Ecto.Changeset{}}} =
|
||||
ReceiverWorker.perform(%Oban.Job{
|
||||
args: %{"op" => "incoming_ap_doc", "params" => params}
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
test "it does not retry duplicates" do
|
||||
params = insert(:note_activity).data
|
||||
|
||||
assert {:cancel, :already_present} =
|
||||
ReceiverWorker.perform(%Oban.Job{
|
||||
args: %{"op" => "incoming_ap_doc", "params" => params}
|
||||
})
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue