summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/fixtures/DSCN0010.pngbin0 -> 762272 bytes
-rw-r--r--test/fixtures/bastianallgeier.json117
-rw-r--r--test/fixtures/denniskoch.json112
-rw-r--r--test/fixtures/receiver_worker_signature_activity.json62
-rw-r--r--test/fixtures/tesla_mock/gleasonator.com_host_meta4
-rw-r--r--test/fixtures/tesla_mock/webfinger_spoof.json28
-rw-r--r--test/fixtures/unindexed_fk.sql27
-rw-r--r--test/fixtures/webfinger/graf-imposter-webfinger.json41
-rw-r--r--test/mix/tasks/pleroma/config_test.exs1
-rw-r--r--test/mix/tasks/pleroma/database_test.exs496
-rw-r--r--test/pleroma/activity_test.exs2
-rw-r--r--test/pleroma/config_db_test.exs2
-rw-r--r--test/pleroma/gun/connection_pool_test.exs1
-rw-r--r--test/pleroma/http/adapter_helper/gun_test.exs12
-rw-r--r--test/pleroma/http/adapter_helper_test.exs4
-rw-r--r--test/pleroma/integration/mastodon_websocket_test.exs8
-rw-r--r--test/pleroma/job_queue_monitor_test.exs12
-rw-r--r--test/pleroma/migration_helper/notification_backfill_test.exs2
-rw-r--r--test/pleroma/notification_test.exs83
-rw-r--r--test/pleroma/object/fetcher_test.exs1
-rw-r--r--test/pleroma/object_test.exs2
-rw-r--r--test/pleroma/resilience_test.exs4
-rw-r--r--test/pleroma/scheduled_activity_test.exs3
-rw-r--r--test/pleroma/schema_test.exs17
-rw-r--r--test/pleroma/search/healthcheck_test.exs49
-rw-r--r--test/pleroma/search/qdrant_search_test.exs199
-rw-r--r--test/pleroma/signature_test.exs8
-rw-r--r--test/pleroma/stats_test.exs4
-rw-r--r--test/pleroma/upload/filter/exiftool/strip_location_test.exs44
-rw-r--r--test/pleroma/uploaders/ipfs_test.exs155
-rw-r--r--test/pleroma/user/backup_async_test.exs2
-rw-r--r--test/pleroma/user/backup_test.exs22
-rw-r--r--test/pleroma/user_test.exs149
-rw-r--r--test/pleroma/web/activity_pub/activity_pub_controller_test.exs13
-rw-r--r--test/pleroma/web/activity_pub/activity_pub_test.exs65
-rw-r--r--test/pleroma/web/activity_pub/mrf/anti_mention_spam_policy_test.exs65
-rw-r--r--test/pleroma/web/activity_pub/mrf/nsfw_api_policy_test.exs267
-rw-r--r--test/pleroma/web/activity_pub/mrf/simple_policy_test.exs2
-rw-r--r--test/pleroma/web/activity_pub/mrf_test.exs1
-rw-r--r--test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs2
-rw-r--r--test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs11
-rw-r--r--test/pleroma/web/activity_pub/object_validators/like_validation_test.exs2
-rw-r--r--test/pleroma/web/activity_pub/object_validators/undo_handling_test.exs2
-rw-r--r--test/pleroma/web/activity_pub/object_validators/update_handling_test.exs2
-rw-r--r--test/pleroma/web/activity_pub/publisher_test.exs3
-rw-r--r--test/pleroma/web/activity_pub/relay_test.exs5
-rw-r--r--test/pleroma/web/activity_pub/side_effects/delete_test.exs2
-rw-r--r--test/pleroma/web/activity_pub/side_effects_test.exs8
-rw-r--r--test/pleroma/web/activity_pub/transmogrifier/accept_handling_test.exs4
-rw-r--r--test/pleroma/web/activity_pub/transmogrifier/announce_handling_test.exs2
-rw-r--r--test/pleroma/web/activity_pub/transmogrifier/delete_handling_test.exs1
-rw-r--r--test/pleroma/web/activity_pub/transmogrifier/emoji_tag_building_test.exs14
-rw-r--r--test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs4
-rw-r--r--test/pleroma/web/activity_pub/transmogrifier/reject_handling_test.exs2
-rw-r--r--test/pleroma/web/activity_pub/transmogrifier_test.exs3
-rw-r--r--test/pleroma/web/activity_pub/utils_test.exs28
-rw-r--r--test/pleroma/web/activity_pub/views/object_view_test.exs2
-rw-r--r--test/pleroma/web/activity_pub/views/user_view_test.exs8
-rw-r--r--test/pleroma/web/admin_api/controllers/config_controller_test.exs49
-rw-r--r--test/pleroma/web/admin_api/controllers/user_controller_test.exs2
-rw-r--r--test/pleroma/web/common_api_test.exs326
-rw-r--r--test/pleroma/web/feed/tag_controller_test.exs26
-rw-r--r--test/pleroma/web/feed/user_controller_test.exs12
-rw-r--r--test/pleroma/web/mastodon_api/controllers/account_controller_test.exs63
-rw-r--r--test/pleroma/web/mastodon_api/controllers/follow_request_controller_test.exs6
-rw-r--r--test/pleroma/web/mastodon_api/controllers/media_controller_test.exs1
-rw-r--r--test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs30
-rw-r--r--test/pleroma/web/mastodon_api/controllers/scheduled_activity_controller_test.exs17
-rw-r--r--test/pleroma/web/mastodon_api/controllers/search_controller_test.exs1
-rw-r--r--test/pleroma/web/mastodon_api/controllers/status_controller_test.exs38
-rw-r--r--test/pleroma/web/mastodon_api/controllers/suggestion_controller_test.exs4
-rw-r--r--test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs2
-rw-r--r--test/pleroma/web/mastodon_api/views/account_view_test.exs26
-rw-r--r--test/pleroma/web/mastodon_api/views/notification_view_test.exs35
-rw-r--r--test/pleroma/web/mastodon_api/views/poll_view_test.exs4
-rw-r--r--test/pleroma/web/mastodon_api/views/status_view_test.exs112
-rw-r--r--test/pleroma/web/metadata/utils_test.exs30
-rw-r--r--test/pleroma/web/o_auth/ldap_authorization_test.exs2
-rw-r--r--test/pleroma/web/o_status/o_status_controller_test.exs2
-rw-r--r--test/pleroma/web/pleroma_api/controllers/account_controller_test.exs30
-rw-r--r--test/pleroma/web/pleroma_api/controllers/emoji_pack_controller_test.exs6
-rw-r--r--test/pleroma/web/pleroma_api/controllers/notification_controller_test.exs27
-rw-r--r--test/pleroma/web/pleroma_api/views/chat_message_reference_view_test.exs3
-rw-r--r--test/pleroma/web/plugs/http_security_plug_test.exs210
-rw-r--r--test/pleroma/web/plugs/http_signature_plug_test.exs180
-rw-r--r--test/pleroma/web/push/impl_test.exs149
-rw-r--r--test/pleroma/web/rich_media/backfill_test.exs26
-rw-r--r--test/pleroma/web/rich_media/card_test.exs17
-rw-r--r--test/pleroma/web/rich_media/parser/ttl/aws_signed_url_test.exs24
-rw-r--r--test/pleroma/web/rich_media/parser/ttl/opengraph_test.exs18
-rw-r--r--test/pleroma/web/rich_media/parser_test.exs20
-rw-r--r--test/pleroma/web/streamer_test.exs50
-rw-r--r--test/pleroma/web/twitter_api/remote_follow_controller_test.exs2
-rw-r--r--test/pleroma/web/web_finger_test.exs53
-rw-r--r--test/pleroma/workers/poll_worker_test.exs49
-rw-r--r--test/pleroma/workers/purge_expired_activity_test.exs4
-rw-r--r--test/pleroma/workers/receiver_worker_test.exs198
-rw-r--r--test/pleroma/workers/remote_fetcher_worker_test.exs8
-rw-r--r--test/support/data_case.ex1
-rw-r--r--test/support/factory.ex1
-rw-r--r--test/support/http_request_mock.ex116
-rw-r--r--test/support/http_signatures_proxy.ex9
-rw-r--r--test/support/mocks.ex1
-rw-r--r--test/test_helper.exs4
104 files changed, 3409 insertions, 776 deletions
diff --git a/test/fixtures/DSCN0010.png b/test/fixtures/DSCN0010.png
new file mode 100644
index 000000000..66f2f05f7
--- /dev/null
+++ b/test/fixtures/DSCN0010.png
Binary files differ
diff --git a/test/fixtures/bastianallgeier.json b/test/fixtures/bastianallgeier.json
new file mode 100644
index 000000000..6b47e7db9
--- /dev/null
+++ b/test/fixtures/bastianallgeier.json
@@ -0,0 +1,117 @@
+{
+ "@context": [
+ "https://www.w3.org/ns/activitystreams",
+ "https://w3id.org/security/v1",
+ {
+ "Curve25519Key": "toot:Curve25519Key",
+ "Device": "toot:Device",
+ "Ed25519Key": "toot:Ed25519Key",
+ "Ed25519Signature": "toot:Ed25519Signature",
+ "EncryptedMessage": "toot:EncryptedMessage",
+ "PropertyValue": "schema:PropertyValue",
+ "alsoKnownAs": {
+ "@id": "as:alsoKnownAs",
+ "@type": "@id"
+ },
+ "cipherText": "toot:cipherText",
+ "claim": {
+ "@id": "toot:claim",
+ "@type": "@id"
+ },
+ "deviceId": "toot:deviceId",
+ "devices": {
+ "@id": "toot:devices",
+ "@type": "@id"
+ },
+ "discoverable": "toot:discoverable",
+ "featured": {
+ "@id": "toot:featured",
+ "@type": "@id"
+ },
+ "featuredTags": {
+ "@id": "toot:featuredTags",
+ "@type": "@id"
+ },
+ "fingerprintKey": {
+ "@id": "toot:fingerprintKey",
+ "@type": "@id"
+ },
+ "focalPoint": {
+ "@container": "@list",
+ "@id": "toot:focalPoint"
+ },
+ "identityKey": {
+ "@id": "toot:identityKey",
+ "@type": "@id"
+ },
+ "indexable": "toot:indexable",
+ "manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
+ "memorial": "toot:memorial",
+ "messageFranking": "toot:messageFranking",
+ "messageType": "toot:messageType",
+ "movedTo": {
+ "@id": "as:movedTo",
+ "@type": "@id"
+ },
+ "publicKeyBase64": "toot:publicKeyBase64",
+ "schema": "http://schema.org#",
+ "suspended": "toot:suspended",
+ "toot": "http://joinmastodon.org/ns#",
+ "value": "schema:value"
+ }
+ ],
+ "attachment": [
+ {
+ "name": "Website",
+ "type": "PropertyValue",
+ "value": "<a href=\"https://bastianallgeier.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\" translate=\"no\"><span class=\"invisible\">https://</span><span class=\"\">bastianallgeier.com</span><span class=\"invisible\"></span></a>"
+ },
+ {
+ "name": "Project",
+ "type": "PropertyValue",
+ "value": "<a href=\"https://getkirby.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\" translate=\"no\"><span class=\"invisible\">https://</span><span class=\"\">getkirby.com</span><span class=\"invisible\"></span></a>"
+ },
+ {
+ "name": "Github",
+ "type": "PropertyValue",
+ "value": "<a href=\"https://github.com/bastianallgeier\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\" translate=\"no\"><span class=\"invisible\">https://</span><span class=\"\">github.com/bastianallgeier</span><span class=\"invisible\"></span></a>"
+ }
+ ],
+ "devices": "https://mastodon.social/users/bastianallgeier/collections/devices",
+ "discoverable": true,
+ "endpoints": {
+ "sharedInbox": "https://mastodon.social/inbox"
+ },
+ "featured": "https://mastodon.social/users/bastianallgeier/collections/featured",
+ "featuredTags": "https://mastodon.social/users/bastianallgeier/collections/tags",
+ "followers": "https://mastodon.social/users/bastianallgeier/followers",
+ "following": "https://mastodon.social/users/bastianallgeier/following",
+ "icon": {
+ "mediaType": "image/jpeg",
+ "type": "Image",
+ "url": "https://files.mastodon.social/accounts/avatars/000/007/393/original/0180a20079617c71.jpg"
+ },
+ "id": "https://mastodon.social/users/bastianallgeier",
+ "image": {
+ "mediaType": "image/jpeg",
+ "type": "Image",
+ "url": "https://files.mastodon.social/accounts/headers/000/007/393/original/13d644ab46d50478.jpeg"
+ },
+ "inbox": "https://mastodon.social/users/bastianallgeier/inbox",
+ "indexable": false,
+ "manuallyApprovesFollowers": false,
+ "memorial": false,
+ "name": "Bastian Allgeier",
+ "outbox": "https://mastodon.social/users/bastianallgeier/outbox",
+ "preferredUsername": "bastianallgeier",
+ "publicKey": {
+ "id": "https://mastodon.social/users/bastianallgeier#main-key",
+ "owner": "https://mastodon.social/users/bastianallgeier",
+ "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3fz+hpgVztO9z6HUhyzv\nwP++ERBBoIwSLKf1TyIM8bvzGFm2YXaO5uxu1HvumYFTYc3ACr3q4j8VUb7NMxkQ\nlzu4QwPjOFJ43O+fY+HSPORXEDW5fXDGC5DGpox4+i08LxRmx7L6YPRUSUuPN8nI\nWyq1Qsq1zOQrNY/rohMXkBdSXxqC3yIRqvtLt4otCgay/5tMogJWkkS6ZKyFhb9z\nwVVy1fsbV10c9C+SHy4NH26CKaTtpTYLRBMjhTCS8bX8iDSjGIf2aZgYs1ir7gEz\n9wf5CvLiENmVWGwm64t6KSEAkA4NJ1hzgHUZPCjPHZE2SmhO/oHaxokTzqtbbENJ\n1QIDAQAB\n-----END PUBLIC KEY-----\n"
+ },
+ "published": "2016-11-01T00:00:00Z",
+ "summary": "<p>Designer &amp; developer. Creator of Kirby CMS</p>",
+ "tag": [],
+ "type": "Person",
+ "url": "https://mastodon.social/@bastianallgeier"
+}
diff --git a/test/fixtures/denniskoch.json b/test/fixtures/denniskoch.json
new file mode 100644
index 000000000..7aa4de508
--- /dev/null
+++ b/test/fixtures/denniskoch.json
@@ -0,0 +1,112 @@
+{
+ "@context": [
+ "https://www.w3.org/ns/activitystreams",
+ "https://w3id.org/security/v1",
+ {
+ "Curve25519Key": "toot:Curve25519Key",
+ "Device": "toot:Device",
+ "Ed25519Key": "toot:Ed25519Key",
+ "Ed25519Signature": "toot:Ed25519Signature",
+ "EncryptedMessage": "toot:EncryptedMessage",
+ "PropertyValue": "schema:PropertyValue",
+ "alsoKnownAs": {
+ "@id": "as:alsoKnownAs",
+ "@type": "@id"
+ },
+ "cipherText": "toot:cipherText",
+ "claim": {
+ "@id": "toot:claim",
+ "@type": "@id"
+ },
+ "deviceId": "toot:deviceId",
+ "devices": {
+ "@id": "toot:devices",
+ "@type": "@id"
+ },
+ "discoverable": "toot:discoverable",
+ "featured": {
+ "@id": "toot:featured",
+ "@type": "@id"
+ },
+ "featuredTags": {
+ "@id": "toot:featuredTags",
+ "@type": "@id"
+ },
+ "fingerprintKey": {
+ "@id": "toot:fingerprintKey",
+ "@type": "@id"
+ },
+ "focalPoint": {
+ "@container": "@list",
+ "@id": "toot:focalPoint"
+ },
+ "identityKey": {
+ "@id": "toot:identityKey",
+ "@type": "@id"
+ },
+ "indexable": "toot:indexable",
+ "manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
+ "memorial": "toot:memorial",
+ "messageFranking": "toot:messageFranking",
+ "messageType": "toot:messageType",
+ "movedTo": {
+ "@id": "as:movedTo",
+ "@type": "@id"
+ },
+ "publicKeyBase64": "toot:publicKeyBase64",
+ "schema": "http://schema.org#",
+ "suspended": "toot:suspended",
+ "toot": "http://joinmastodon.org/ns#",
+ "value": "schema:value"
+ }
+ ],
+ "attachment": [
+ {
+ "name": "GitHub",
+ "type": "PropertyValue",
+ "value": "<a href=\"https://github.com/pxlrbt/\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\" translate=\"no\"><span class=\"invisible\">https://</span><span class=\"\">github.com/pxlrbt/</span><span class=\"invisible\"></span></a>"
+ },
+ {
+ "name": "Discord",
+ "type": "PropertyValue",
+ "value": "pxlrbt#6029"
+ }
+ ],
+ "devices": "https://phpc.social/users/denniskoch/collections/devices",
+ "discoverable": true,
+ "endpoints": {
+ "sharedInbox": "https://phpc.social/inbox"
+ },
+ "featured": "https://phpc.social/users/denniskoch/collections/featured",
+ "featuredTags": "https://phpc.social/users/denniskoch/collections/tags",
+ "followers": "https://phpc.social/users/denniskoch/followers",
+ "following": "https://phpc.social/users/denniskoch/following",
+ "icon": {
+ "mediaType": "image/jpeg",
+ "type": "Image",
+ "url": "https://media.phpc.social/accounts/avatars/109/364/097/179/042/485/original/6e770c7b3f5ef72d.jpg"
+ },
+ "id": "https://phpc.social/users/denniskoch",
+ "image": {
+ "mediaType": "image/jpeg",
+ "type": "Image",
+ "url": "https://media.phpc.social/accounts/headers/109/364/097/179/042/485/original/709da24705260c04.jpg"
+ },
+ "inbox": "https://phpc.social/users/denniskoch/inbox",
+ "indexable": true,
+ "manuallyApprovesFollowers": false,
+ "memorial": false,
+ "name": "Dennis Koch",
+ "outbox": "https://phpc.social/users/denniskoch/outbox",
+ "preferredUsername": "denniskoch",
+ "publicKey": {
+ "id": "https://phpc.social/users/denniskoch#main-key",
+ "owner": "https://phpc.social/users/denniskoch",
+ "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4dmcSlqLj18gPvuslkmt\nQTniZ8ybO4pgvMvPLYtBuTBUjo49vJ/8Sw6jB5zcKb1haqIdny7Rv/vY3kCdCXcP\nloh1I+jthEgqLT8JpZWGwLGwg9piFhrMGADmt3N8du7HfglzuZ8LlVpnZ8feCw7I\nS2ua/ZCxE47mI45Z3ed2kkFYKWopWWqFn2lan/1OyHrcFKtCvaVjRdvo0UUt2tgl\nvyJI4+zN8FnrCbsMtcbI5nSzfJIrOc4LeaGmLJh+0o2rwoOQZc2487XWbeyfhjsq\nPRBpYN7pfHWQDvzQIN075LHTf9zDFsm6+HqY7Zs5rYxr72rvcX7d9JcP6CasIosY\nqwIDAQAB\n-----END PUBLIC KEY-----\n"
+ },
+ "published": "2022-11-18T00:00:00Z",
+ "summary": "<p>🧑‍💻 Full Stack Developer<br />🚀 Laravel, Filament, Livewire, Vue, Inertia<br />🌍 Germany</p>",
+ "tag": [],
+ "type": "Person",
+ "url": "https://phpc.social/@denniskoch"
+}
diff --git a/test/fixtures/receiver_worker_signature_activity.json b/test/fixtures/receiver_worker_signature_activity.json
new file mode 100644
index 000000000..3c3fb3fd2
--- /dev/null
+++ b/test/fixtures/receiver_worker_signature_activity.json
@@ -0,0 +1,62 @@
+{
+ "@context": [
+ "https://www.w3.org/ns/activitystreams",
+ {
+ "atomUri": "ostatus:atomUri",
+ "blurhash": "toot:blurhash",
+ "conversation": "ostatus:conversation",
+ "focalPoint": {
+ "@container": "@list",
+ "@id": "toot:focalPoint"
+ },
+ "inReplyToAtomUri": "ostatus:inReplyToAtomUri",
+ "ostatus": "http://ostatus.org#",
+ "sensitive": "as:sensitive",
+ "toot": "http://joinmastodon.org/ns#",
+ "votersCount": "toot:votersCount"
+ }
+ ],
+ "atomUri": "https://chaos.social/users/distantnative/statuses/109336635639931467",
+ "attachment": [
+ {
+ "blurhash": "UAK1zS00OXIUxuMxIUM{?b-:-;W:Di?b%2M{",
+ "height": 960,
+ "mediaType": "image/jpeg",
+ "name": null,
+ "type": "Document",
+ "url": "https://assets.chaos.social/media_attachments/files/109/336/634/286/114/657/original/2e6122063d8bfb26.jpeg",
+ "width": 346
+ }
+ ],
+ "attributedTo": "https://chaos.social/users/distantnative",
+ "cc": [
+ "https://chaos.social/users/distantnative/followers"
+ ],
+ "content": "<p>Favorite piece of anthropology meta discourse.</p>",
+ "contentMap": {
+ "en": "<p>Favorite piece of anthropology meta discourse.</p>"
+ },
+ "conversation": "tag:chaos.social,2022-11-13:objectId=71843781:objectType=Conversation",
+ "id": "https://chaos.social/users/distantnative/statuses/109336635639931467",
+ "inReplyTo": null,
+ "inReplyToAtomUri": null,
+ "published": "2022-11-13T13:04:20Z",
+ "replies": {
+ "first": {
+ "items": [],
+ "next": "https://chaos.social/users/distantnative/statuses/109336635639931467/replies?only_other_accounts=true&page=true",
+ "partOf": "https://chaos.social/users/distantnative/statuses/109336635639931467/replies",
+ "type": "CollectionPage"
+ },
+ "id": "https://chaos.social/users/distantnative/statuses/109336635639931467/replies",
+ "type": "Collection"
+ },
+ "sensitive": false,
+ "summary": null,
+ "tag": [],
+ "to": [
+ "https://www.w3.org/ns/activitystreams#Public"
+ ],
+ "type": "Note",
+ "url": "https://chaos.social/@distantnative/109336635639931467"
+}
diff --git a/test/fixtures/tesla_mock/gleasonator.com_host_meta b/test/fixtures/tesla_mock/gleasonator.com_host_meta
new file mode 100644
index 000000000..c1a432519
--- /dev/null
+++ b/test/fixtures/tesla_mock/gleasonator.com_host_meta
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
+ <Link rel="lrdd" template="https://gleasonator.com/.well-known/webfinger?resource={uri}" type="application/xrd+xml" />
+</XRD> \ No newline at end of file
diff --git a/test/fixtures/tesla_mock/webfinger_spoof.json b/test/fixtures/tesla_mock/webfinger_spoof.json
new file mode 100644
index 000000000..7c2a11f69
--- /dev/null
+++ b/test/fixtures/tesla_mock/webfinger_spoof.json
@@ -0,0 +1,28 @@
+{
+ "aliases": [
+ "https://gleasonator.com/users/alex",
+ "https://mitra.social/users/alex"
+ ],
+ "links": [
+ {
+ "href": "https://gleasonator.com/users/alex",
+ "rel": "http://webfinger.net/rel/profile-page",
+ "type": "text/html"
+ },
+ {
+ "href": "https://gleasonator.com/users/alex",
+ "rel": "self",
+ "type": "application/activity+json"
+ },
+ {
+ "href": "https://gleasonator.com/users/alex",
+ "rel": "self",
+ "type": "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
+ },
+ {
+ "rel": "http://ostatus.org/schema/1.0/subscribe",
+ "template": "https://gleasonator.com/ostatus_subscribe?acct={uri}"
+ }
+ ],
+ "subject": "acct:trump@whitehouse.gov"
+}
diff --git a/test/fixtures/unindexed_fk.sql b/test/fixtures/unindexed_fk.sql
new file mode 100644
index 000000000..3b71679cf
--- /dev/null
+++ b/test/fixtures/unindexed_fk.sql
@@ -0,0 +1,27 @@
+-- Unindexed FK -- Missing indexes - For CI
+
+WITH y AS (
+SELECT
+pg_catalog.format('%I', c1.relname) AS referencing_tbl,
+pg_catalog.quote_ident(a1.attname) AS referencing_column,
+(SELECT pg_get_expr(indpred, indrelid) FROM pg_catalog.pg_index WHERE indrelid = t.conrelid AND indkey[0] = t.conkey[1] AND indpred IS NOT NULL LIMIT 1) partial_statement
+FROM pg_catalog.pg_constraint t
+JOIN pg_catalog.pg_attribute a1 ON a1.attrelid = t.conrelid AND a1.attnum = t.conkey[1]
+JOIN pg_catalog.pg_class c1 ON c1.oid = t.conrelid
+JOIN pg_catalog.pg_namespace n1 ON n1.oid = c1.relnamespace
+JOIN pg_catalog.pg_class c2 ON c2.oid = t.confrelid
+JOIN pg_catalog.pg_namespace n2 ON n2.oid = c2.relnamespace
+JOIN pg_catalog.pg_attribute a2 ON a2.attrelid = t.confrelid AND a2.attnum = t.confkey[1]
+WHERE t.contype = 'f'
+AND NOT EXISTS (
+SELECT 1
+FROM pg_catalog.pg_index i
+WHERE i.indrelid = t.conrelid
+AND i.indkey[0] = t.conkey[1]
+AND indpred IS NULL
+)
+)
+SELECT referencing_tbl || '.' || referencing_column as "column"
+FROM y
+WHERE (partial_statement IS NULL OR partial_statement <> ('(' || referencing_column || ' IS NOT NULL)'))
+ORDER BY 1; \ No newline at end of file
diff --git a/test/fixtures/webfinger/graf-imposter-webfinger.json b/test/fixtures/webfinger/graf-imposter-webfinger.json
new file mode 100644
index 000000000..e7010f606
--- /dev/null
+++ b/test/fixtures/webfinger/graf-imposter-webfinger.json
@@ -0,0 +1,41 @@
+{
+ "subject": "acct:graf@poa.st",
+ "aliases": [
+ "https://fba.ryona.agenc/webfingertest"
+ ],
+ "links": [
+ {
+ "rel": "http://webfinger.net/rel/profile-page",
+ "type": "text/html",
+ "href": "https://fba.ryona.agenc/webfingertest"
+ },
+ {
+ "rel": "self",
+ "type": "application/activity+json",
+ "href": "https://fba.ryona.agenc/webfingertest"
+ },
+ {
+ "rel": "http://ostatus.org/schema/1.0/subscribe",
+ "template": "https://fba.ryona.agenc/contact/follow?url={uri}"
+ },
+ {
+ "rel": "http://schemas.google.com/g/2010#updates-from",
+ "type": "application/atom+xml",
+ "href": ""
+ },
+ {
+ "rel": "salmon",
+ "href": "https://fba.ryona.agenc/salmon/friendica"
+ },
+ {
+ "rel": "http://microformats.org/profile/hcard",
+ "type": "text/html",
+ "href": "https://fba.ryona.agenc/hcard/friendica"
+ },
+ {
+ "rel": "http://joindiaspora.com/seed_location",
+ "type": "text/html",
+ "href": "https://fba.ryona.agenc"
+ }
+ ]
+}
diff --git a/test/mix/tasks/pleroma/config_test.exs b/test/mix/tasks/pleroma/config_test.exs
index 7b2134129..942cfa83d 100644
--- a/test/mix/tasks/pleroma/config_test.exs
+++ b/test/mix/tasks/pleroma/config_test.exs
@@ -51,7 +51,6 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
clear_config(:configurable_from_database, true)
end
- @tag capture_log: true
test "config migration refused when deprecated settings are found" do
clear_config([:media_proxy, :whitelist], ["domain_without_scheme.com"])
assert config_records() == []
diff --git a/test/mix/tasks/pleroma/database_test.exs b/test/mix/tasks/pleroma/database_test.exs
index fbc939171..a51a3bf3d 100644
--- a/test/mix/tasks/pleroma/database_test.exs
+++ b/test/mix/tasks/pleroma/database_test.exs
@@ -7,6 +7,7 @@ defmodule Mix.Tasks.Pleroma.DatabaseTest do
use Oban.Testing, repo: Pleroma.Repo
alias Pleroma.Activity
+ alias Pleroma.Bookmark
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.User
@@ -45,28 +46,509 @@ defmodule Mix.Tasks.Pleroma.DatabaseTest do
end
describe "prune_objects" do
- test "it prunes old objects from the database" do
- insert(:note)
+ setup do
deadline = Pleroma.Config.get([:instance, :remote_post_retention_days]) + 1
- date =
+ old_insert_date =
Timex.now()
|> Timex.shift(days: -deadline)
|> Timex.to_naive_datetime()
|> NaiveDateTime.truncate(:second)
- %{id: id} =
+ %{old_insert_date: old_insert_date}
+ end
+
+ test "it prunes old objects from the database", %{old_insert_date: old_insert_date} do
+ insert(:note)
+
+ %{id: note_remote_public_id} =
:note
|> insert()
- |> Ecto.Changeset.change(%{inserted_at: date})
+ |> Ecto.Changeset.change(%{updated_at: old_insert_date})
|> Repo.update!()
+ note_remote_non_public =
+ %{id: note_remote_non_public_id, data: note_remote_non_public_data} =
+ :note
+ |> insert()
+
+ note_remote_non_public
+ |> Ecto.Changeset.change(%{
+ updated_at: old_insert_date,
+ data: note_remote_non_public_data |> update_in(["to"], fn _ -> [] end)
+ })
+ |> Repo.update!()
+
+ assert length(Repo.all(Object)) == 3
+
+ Mix.Tasks.Pleroma.Database.run(["prune_objects"])
+
+ assert length(Repo.all(Object)) == 1
+ refute Object.get_by_id(note_remote_public_id)
+ refute Object.get_by_id(note_remote_non_public_id)
+ end
+
+ test "it cleans up bookmarks", %{old_insert_date: old_insert_date} do
+ user = insert(:user)
+ {:ok, old_object_activity} = CommonAPI.post(user, %{status: "yadayada"})
+
+ Repo.one(Object)
+ |> Ecto.Changeset.change(%{updated_at: old_insert_date})
+ |> Repo.update!()
+
+ {:ok, new_object_activity} = CommonAPI.post(user, %{status: "yadayada"})
+
+ {:ok, _} = Bookmark.create(user.id, old_object_activity.id)
+ {:ok, _} = Bookmark.create(user.id, new_object_activity.id)
+
assert length(Repo.all(Object)) == 2
+ assert length(Repo.all(Bookmark)) == 2
Mix.Tasks.Pleroma.Database.run(["prune_objects"])
assert length(Repo.all(Object)) == 1
- refute Object.get_by_id(id)
+ assert length(Repo.all(Bookmark)) == 1
+ refute Bookmark.get(user.id, old_object_activity.id)
+ end
+
+ test "with the --keep-non-public option it still keeps non-public posts even if they are not local",
+ %{old_insert_date: old_insert_date} do
+ insert(:note)
+
+ %{id: note_remote_id} =
+ :note
+ |> insert()
+ |> Ecto.Changeset.change(%{updated_at: old_insert_date})
+ |> Repo.update!()
+
+ note_remote_non_public =
+ %{data: note_remote_non_public_data} =
+ :note
+ |> insert()
+
+ note_remote_non_public
+ |> Ecto.Changeset.change(%{
+ updated_at: old_insert_date,
+ data: note_remote_non_public_data |> update_in(["to"], fn _ -> [] end)
+ })
+ |> Repo.update!()
+
+ assert length(Repo.all(Object)) == 3
+
+ Mix.Tasks.Pleroma.Database.run(["prune_objects", "--keep-non-public"])
+
+ assert length(Repo.all(Object)) == 2
+ refute Object.get_by_id(note_remote_id)
+ end
+
+ test "with the --keep-threads and --keep-non-public option it keeps old threads with non-public replies even if the interaction is not local",
+ %{old_insert_date: old_insert_date} do
+ # For non-public we only check Create Activities because only these are relevant for threads
+ # Flags are always non-public, Announces from relays can be non-public...
+
+ remote_user1 = insert(:user, local: false)
+ remote_user2 = insert(:user, local: false)
+
+ # Old remote non-public reply (should be kept)
+ {:ok, old_remote_post1_activity} =
+ CommonAPI.post(remote_user1, %{status: "some thing", local: false})
+
+ old_remote_post1_activity
+ |> Ecto.Changeset.change(%{local: false, updated_at: old_insert_date})
+ |> Repo.update!()
+
+ {:ok, old_remote_non_public_reply_activity} =
+ CommonAPI.post(remote_user2, %{
+ status: "some reply",
+ in_reply_to_status_id: old_remote_post1_activity.id
+ })
+
+ old_remote_non_public_reply_activity
+ |> Ecto.Changeset.change(%{
+ local: false,
+ updated_at: old_insert_date,
+ data: old_remote_non_public_reply_activity.data |> update_in(["to"], fn _ -> [] end)
+ })
+ |> Repo.update!()
+
+ # Old remote non-public Announce (should be removed)
+ {:ok, old_remote_post2_activity = %{data: %{"object" => old_remote_post2_id}}} =
+ CommonAPI.post(remote_user1, %{status: "some thing", local: false})
+
+ old_remote_post2_activity
+ |> Ecto.Changeset.change(%{local: false, updated_at: old_insert_date})
+ |> Repo.update!()
+
+ {:ok, old_remote_non_public_repeat_activity} =
+ CommonAPI.repeat(old_remote_post2_activity.id, remote_user2)
+
+ old_remote_non_public_repeat_activity
+ |> Ecto.Changeset.change(%{
+ local: false,
+ updated_at: old_insert_date,
+ data: old_remote_non_public_repeat_activity.data |> update_in(["to"], fn _ -> [] end)
+ })
+ |> Repo.update!()
+
+ assert length(Repo.all(Object)) == 3
+
+ Mix.Tasks.Pleroma.Database.run(["prune_objects", "--keep-threads", "--keep-non-public"])
+
+ Repo.all(Pleroma.Activity)
+ assert length(Repo.all(Object)) == 2
+ refute Object.get_by_ap_id(old_remote_post2_id)
+ end
+
+ test "with the --keep-threads option it still keeps non-old threads even with no local interactions" do
+ remote_user = insert(:user, local: false)
+ remote_user2 = insert(:user, local: false)
+
+ {:ok, remote_post_activity} =
+ CommonAPI.post(remote_user, %{status: "some thing", local: false})
+
+ {:ok, remote_post_reply_activity} =
+ CommonAPI.post(remote_user2, %{
+ status: "some reply",
+ in_reply_to_status_id: remote_post_activity.id
+ })
+
+ remote_post_activity
+ |> Ecto.Changeset.change(%{local: false})
+ |> Repo.update!()
+
+ remote_post_reply_activity
+ |> Ecto.Changeset.change(%{local: false})
+ |> Repo.update!()
+
+ assert length(Repo.all(Object)) == 2
+
+ Mix.Tasks.Pleroma.Database.run(["prune_objects", "--keep-threads"])
+
+ assert length(Repo.all(Object)) == 2
+ end
+
+ test "with the --keep-threads option it deletes old threads with no local interaction", %{
+ old_insert_date: old_insert_date
+ } do
+ remote_user = insert(:user, local: false)
+ remote_user2 = insert(:user, local: false)
+
+ {:ok, old_remote_post_activity} =
+ CommonAPI.post(remote_user, %{status: "some thing", local: false})
+
+ old_remote_post_activity
+ |> Ecto.Changeset.change(%{local: false, updated_at: old_insert_date})
+ |> Repo.update!()
+
+ {:ok, old_remote_post_reply_activity} =
+ CommonAPI.post(remote_user2, %{
+ status: "some reply",
+ in_reply_to_status_id: old_remote_post_activity.id
+ })
+
+ old_remote_post_reply_activity
+ |> Ecto.Changeset.change(%{local: false, updated_at: old_insert_date})
+ |> Repo.update!()
+
+ {:ok, old_favourite_activity} =
+ CommonAPI.favorite(old_remote_post_activity.id, remote_user2)
+
+ old_favourite_activity
+ |> Ecto.Changeset.change(%{local: false, updated_at: old_insert_date})
+ |> Repo.update!()
+
+ {:ok, old_repeat_activity} = CommonAPI.repeat(old_remote_post_activity.id, remote_user2)
+
+ old_repeat_activity
+ |> Ecto.Changeset.change(%{local: false, updated_at: old_insert_date})
+ |> Repo.update!()
+
+ assert length(Repo.all(Object)) == 2
+
+ Mix.Tasks.Pleroma.Database.run(["prune_objects", "--keep-threads"])
+
+ assert length(Repo.all(Object)) == 0
+ end
+
+ test "with the --keep-threads option it keeps old threads with local interaction", %{
+ old_insert_date: old_insert_date
+ } do
+ remote_user = insert(:user, local: false)
+ local_user = insert(:user, local: true)
+
+ # local reply
+ {:ok, old_remote_post1_activity} =
+ CommonAPI.post(remote_user, %{status: "some thing", local: false})
+
+ old_remote_post1_activity
+ |> Ecto.Changeset.change(%{local: false, updated_at: old_insert_date})
+ |> Repo.update!()
+
+ {:ok, old_local_post2_reply_activity} =
+ CommonAPI.post(local_user, %{
+ status: "some reply",
+ in_reply_to_status_id: old_remote_post1_activity.id
+ })
+
+ old_local_post2_reply_activity
+ |> Ecto.Changeset.change(%{local: true, updated_at: old_insert_date})
+ |> Repo.update!()
+
+ # local Like
+ {:ok, old_remote_post3_activity} =
+ CommonAPI.post(remote_user, %{status: "some thing", local: false})
+
+ old_remote_post3_activity
+ |> Ecto.Changeset.change(%{local: false, updated_at: old_insert_date})
+ |> Repo.update!()
+
+ {:ok, old_favourite_activity} = CommonAPI.favorite(old_remote_post3_activity.id, local_user)
+
+ old_favourite_activity
+ |> Ecto.Changeset.change(%{local: true, updated_at: old_insert_date})
+ |> Repo.update!()
+
+ # local Announce
+ {:ok, old_remote_post4_activity} =
+ CommonAPI.post(remote_user, %{status: "some thing", local: false})
+
+ old_remote_post4_activity
+ |> Ecto.Changeset.change(%{local: false, updated_at: old_insert_date})
+ |> Repo.update!()
+
+ {:ok, old_repeat_activity} = CommonAPI.repeat(old_remote_post4_activity.id, local_user)
+
+ old_repeat_activity
+ |> Ecto.Changeset.change(%{local: true, updated_at: old_insert_date})
+ |> Repo.update!()
+
+ assert length(Repo.all(Object)) == 4
+
+ Mix.Tasks.Pleroma.Database.run(["prune_objects", "--keep-threads"])
+
+ assert length(Repo.all(Object)) == 4
+ end
+
+ test "with the --keep-threads option it keeps old threads with bookmarked posts", %{
+ old_insert_date: old_insert_date
+ } do
+ remote_user = insert(:user, local: false)
+ local_user = insert(:user, local: true)
+
+ {:ok, old_remote_post_activity} =
+ CommonAPI.post(remote_user, %{status: "some thing", local: false})
+
+ old_remote_post_activity
+ |> Ecto.Changeset.change(%{local: false, updated_at: old_insert_date})
+ |> Repo.update!()
+
+ Pleroma.Bookmark.create(local_user.id, old_remote_post_activity.id)
+
+ assert length(Repo.all(Object)) == 1
+
+ Mix.Tasks.Pleroma.Database.run(["prune_objects", "--keep-threads"])
+
+ assert length(Repo.all(Object)) == 1
+ end
+
+ test "We don't have unexpected tables which may contain objects that are referenced by activities" do
+ # We can delete orphaned activities. For that we look for the objects
+ # they reference in the 'objects', 'activities', and 'users' table.
+ # If someone adds another table with objects (idk, maybe with separate
+ # relations, or collections or w/e), then we need to make sure we
+ # add logic for that in the 'prune_objects' task so that we don't
+ # wrongly delete their corresponding activities.
+ # So when someone adds (or removes) a table, this test will fail.
+ # Either the table contains objects which can be referenced from the
+ # activities table
+ # => in that case the prune_objects job should be adapted so we don't
+ # delete activities who still have the referenced object.
+ # Or it doesn't contain objects which can be referenced from the activities table
+ # => in that case you can add/remove the table to/from this (sorted) list.
+
+ assert Repo.query!(
+ "SELECT table_name FROM information_schema.tables WHERE table_schema='public' AND table_type='BASE TABLE';"
+ ).rows
+ |> Enum.sort() == [
+ ["activities"],
+ ["announcement_read_relationships"],
+ ["announcements"],
+ ["apps"],
+ ["backups"],
+ ["bookmark_folders"],
+ ["bookmarks"],
+ ["chat_message_references"],
+ ["chats"],
+ ["config"],
+ ["conversation_participation_recipient_ships"],
+ ["conversation_participations"],
+ ["conversations"],
+ ["counter_cache"],
+ ["data_migration_failed_ids"],
+ ["data_migrations"],
+ ["deliveries"],
+ ["filters"],
+ ["following_relationships"],
+ ["hashtags"],
+ ["hashtags_objects"],
+ ["instances"],
+ ["lists"],
+ ["markers"],
+ ["mfa_tokens"],
+ ["moderation_log"],
+ ["notifications"],
+ ["oauth_authorizations"],
+ ["oauth_tokens"],
+ ["oban_jobs"],
+ ["oban_peers"],
+ ["objects"],
+ ["password_reset_tokens"],
+ ["push_subscriptions"],
+ ["registrations"],
+ ["report_notes"],
+ ["rich_media_card"],
+ ["rules"],
+ ["scheduled_activities"],
+ ["schema_migrations"],
+ ["thread_mutes"],
+ # ["user_follows_hashtag"], # not in pleroma
+ # ["user_frontend_setting_profiles"], # not in pleroma
+ ["user_invite_tokens"],
+ ["user_notes"],
+ ["user_relationships"],
+ ["users"]
+ ]
+ end
+
+ test "it prunes orphaned activities with the --prune-orphaned-activities" do
+ # Add a remote activity which references an Object
+ %Object{} |> Map.merge(%{data: %{"id" => "object_for_activity"}}) |> Repo.insert()
+
+ %Activity{}
+ |> Map.merge(%{
+ local: false,
+ data: %{"id" => "remote_activity_with_object", "object" => "object_for_activity"}
+ })
+ |> Repo.insert()
+
+ # Add a remote activity which references an activity
+ %Activity{}
+ |> Map.merge(%{
+ local: false,
+ data: %{
+ "id" => "remote_activity_with_activity",
+ "object" => "remote_activity_with_object"
+ }
+ })
+ |> Repo.insert()
+
+ # Add a remote activity which references an Actor
+ %User{} |> Map.merge(%{ap_id: "actor"}) |> Repo.insert()
+
+ %Activity{}
+ |> Map.merge(%{
+ local: false,
+ data: %{"id" => "remote_activity_with_actor", "object" => "actor"}
+ })
+ |> Repo.insert()
+
+ # Add a remote activity without existing referenced object, activity or actor
+ %Activity{}
+ |> Map.merge(%{
+ local: false,
+ data: %{
+ "id" => "remote_activity_without_existing_referenced_object",
+ "object" => "non_existing"
+ }
+ })
+ |> Repo.insert()
+
+ # Add a local activity without existing referenced object, activity or actor
+ %Activity{}
+ |> Map.merge(%{
+ local: true,
+ data: %{"id" => "local_activity_with_actor", "object" => "non_existing"}
+ })
+ |> Repo.insert()
+
+ # The remote activities without existing reference,
+ # and only the remote activities without existing reference, are deleted
+ # if, and only if, we provide the --prune-orphaned-activities option
+ assert length(Repo.all(Activity)) == 5
+ Mix.Tasks.Pleroma.Database.run(["prune_objects"])
+ assert length(Repo.all(Activity)) == 5
+ Mix.Tasks.Pleroma.Database.run(["prune_objects", "--prune-orphaned-activities"])
+ activities = Repo.all(Activity)
+
+ assert "remote_activity_without_existing_referenced_object" not in Enum.map(
+ activities,
+ fn a -> a.data["id"] end
+ )
+
+ assert length(activities) == 4
+ end
+
+ test "it prunes orphaned activities with the --prune-orphaned-activities when the objects are referenced from an array" do
+ %Object{} |> Map.merge(%{data: %{"id" => "existing_object"}}) |> Repo.insert()
+ %User{} |> Map.merge(%{ap_id: "existing_actor"}) |> Repo.insert()
+
+ # Multiple objects, one object exists (keep)
+ %Activity{}
+ |> Map.merge(%{
+ local: false,
+ data: %{
+ "id" => "remote_activity_existing_object",
+ "object" => ["non_ existing_object", "existing_object"]
+ }
+ })
+ |> Repo.insert()
+
+ # Multiple objects, one actor exists (keep)
+ %Activity{}
+ |> Map.merge(%{
+ local: false,
+ data: %{
+ "id" => "remote_activity_existing_actor",
+ "object" => ["non_ existing_object", "existing_actor"]
+ }
+ })
+ |> Repo.insert()
+
+ # Multiple objects, one activity exists (keep)
+ %Activity{}
+ |> Map.merge(%{
+ local: false,
+ data: %{
+ "id" => "remote_activity_existing_activity",
+ "object" => ["non_ existing_object", "remote_activity_existing_actor"]
+ }
+ })
+ |> Repo.insert()
+
+ # Multiple objects none exist (prune)
+ %Activity{}
+ |> Map.merge(%{
+ local: false,
+ data: %{
+ "id" => "remote_activity_without_existing_referenced_object",
+ "object" => ["owo", "whats_this"]
+ }
+ })
+ |> Repo.insert()
+
+ assert length(Repo.all(Activity)) == 4
+ Mix.Tasks.Pleroma.Database.run(["prune_objects"])
+ assert length(Repo.all(Activity)) == 4
+ Mix.Tasks.Pleroma.Database.run(["prune_objects", "--prune-orphaned-activities"])
+ activities = Repo.all(Activity)
+ assert length(activities) == 3
+
+ assert "remote_activity_without_existing_referenced_object" not in Enum.map(
+ activities,
+ fn a -> a.data["id"] end
+ )
+
+ assert length(activities) == 3
end
end
@@ -104,7 +586,7 @@ defmodule Mix.Tasks.Pleroma.DatabaseTest do
{:ok, %{id: id, object: object}} = CommonAPI.post(user, %{status: "test"})
{:ok, %{object: object2}} = CommonAPI.post(user, %{status: "test test"})
- CommonAPI.favorite(user2, id)
+ CommonAPI.favorite(id, user2)
likes = %{
"first" =>
diff --git a/test/pleroma/activity_test.exs b/test/pleroma/activity_test.exs
index 67943d879..62d07b1ee 100644
--- a/test/pleroma/activity_test.exs
+++ b/test/pleroma/activity_test.exs
@@ -249,7 +249,7 @@ defmodule Pleroma.ActivityTest do
{:ok, %{id: id, object: %{data: %{"id" => obj_id}}}} =
Pleroma.Web.CommonAPI.post(user, %{status: "cofe"})
- Pleroma.Web.CommonAPI.favorite(another, id)
+ Pleroma.Web.CommonAPI.favorite(id, another)
assert obj_id
|> Pleroma.Activity.Queries.by_object_id()
diff --git a/test/pleroma/config_db_test.exs b/test/pleroma/config_db_test.exs
index e20da1574..d68e4e6fa 100644
--- a/test/pleroma/config_db_test.exs
+++ b/test/pleroma/config_db_test.exs
@@ -312,7 +312,7 @@ defmodule Pleroma.ConfigDBTest do
test "proxy tuple with domain" do
assert ConfigDB.to_elixir_types(%{
"tuple" => [":proxy_url", %{"tuple" => [":socks5", "domain.com", 1234]}]
- }) == {:proxy_url, {:socks5, 'domain.com', 1234}}
+ }) == {:proxy_url, {:socks5, ~c"domain.com", 1234}}
end
test "proxy tuple with ip" do
diff --git a/test/pleroma/gun/connection_pool_test.exs b/test/pleroma/gun/connection_pool_test.exs
index e0c9e9904..f3670760d 100644
--- a/test/pleroma/gun/connection_pool_test.exs
+++ b/test/pleroma/gun/connection_pool_test.exs
@@ -46,7 +46,6 @@ defmodule Pleroma.Gun.ConnectionPoolTest do
end
end
- @tag :erratic
test "connection limit is respected with concurrent requests" do
clear_config([:connections_pool, :max_connections]) do
clear_config([:connections_pool, :max_connections], 1)
diff --git a/test/pleroma/http/adapter_helper/gun_test.exs b/test/pleroma/http/adapter_helper/gun_test.exs
index d567bc844..568fd6fb3 100644
--- a/test/pleroma/http/adapter_helper/gun_test.exs
+++ b/test/pleroma/http/adapter_helper/gun_test.exs
@@ -55,23 +55,23 @@ defmodule Pleroma.HTTP.AdapterHelper.GunTest do
uri = URI.parse("https://some-domain.com")
opts = Gun.options([receive_conn: false], uri)
- assert opts[:proxy] == {'localhost', 8123}
+ assert opts[:proxy] == {~c"localhost", 8123}
end
test "parses tuple proxy scheme host and port" do
- clear_config([:http, :proxy_url], {:socks, 'localhost', 1234})
+ clear_config([:http, :proxy_url], {:socks, ~c"localhost", 1234})
uri = URI.parse("https://some-domain.com")
opts = Gun.options([receive_conn: false], uri)
- assert opts[:proxy] == {:socks, 'localhost', 1234}
+ assert opts[:proxy] == {:socks, ~c"localhost", 1234}
end
test "passed opts have more weight than defaults" do
- clear_config([:http, :proxy_url], {:socks5, 'localhost', 1234})
+ clear_config([:http, :proxy_url], {:socks5, ~c"localhost", 1234})
uri = URI.parse("https://some-domain.com")
- opts = Gun.options([receive_conn: false, proxy: {'example.com', 4321}], uri)
+ opts = Gun.options([receive_conn: false, proxy: {~c"example.com", 4321}], uri)
- assert opts[:proxy] == {'example.com', 4321}
+ assert opts[:proxy] == {~c"example.com", 4321}
end
end
end
diff --git a/test/pleroma/http/adapter_helper_test.exs b/test/pleroma/http/adapter_helper_test.exs
index e3c78f317..cc0e24167 100644
--- a/test/pleroma/http/adapter_helper_test.exs
+++ b/test/pleroma/http/adapter_helper_test.exs
@@ -17,12 +17,12 @@ defmodule Pleroma.HTTP.AdapterHelperTest do
end
test "localhost with port" do
- assert AdapterHelper.format_proxy("localhost:8123") == {'localhost', 8123}
+ assert AdapterHelper.format_proxy("localhost:8123") == {~c"localhost", 8123}
end
test "tuple" do
assert AdapterHelper.format_proxy({:socks4, :localhost, 9050}) ==
- {:socks4, 'localhost', 9050}
+ {:socks4, ~c"localhost", 9050}
end
end
end
diff --git a/test/pleroma/integration/mastodon_websocket_test.exs b/test/pleroma/integration/mastodon_websocket_test.exs
index a0ffddf8d..f499f54ad 100644
--- a/test/pleroma/integration/mastodon_websocket_test.exs
+++ b/test/pleroma/integration/mastodon_websocket_test.exs
@@ -404,7 +404,7 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
test "receives private statuses", %{user: reading_user, token: token} do
user = insert(:user)
- CommonAPI.follow(reading_user, user)
+ CommonAPI.follow(user, reading_user)
{:ok, _} = start_socket("?stream=user&access_token=#{token.token}")
@@ -431,7 +431,7 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
test "receives edits", %{user: reading_user, token: token} do
user = insert(:user)
- CommonAPI.follow(reading_user, user)
+ CommonAPI.follow(user, reading_user)
{:ok, _} = start_socket("?stream=user&access_token=#{token.token}")
@@ -440,7 +440,7 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
assert_receive {:text, _raw_json}, 1_000
- {:ok, _} = CommonAPI.update(user, activity, %{status: "mew mew", visibility: "private"})
+ {:ok, _} = CommonAPI.update(activity, user, %{status: "mew mew", visibility: "private"})
assert_receive {:text, raw_json}, 1_000
@@ -459,7 +459,7 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
test "receives notifications", %{user: reading_user, token: token} do
user = insert(:user)
- CommonAPI.follow(reading_user, user)
+ CommonAPI.follow(user, reading_user)
{:ok, _} = start_socket("?stream=user:notification&access_token=#{token.token}")
diff --git a/test/pleroma/job_queue_monitor_test.exs b/test/pleroma/job_queue_monitor_test.exs
index f2056990f..e2250d7e2 100644
--- a/test/pleroma/job_queue_monitor_test.exs
+++ b/test/pleroma/job_queue_monitor_test.exs
@@ -28,13 +28,13 @@ defmodule Pleroma.JobQueueMonitorTest do
queue: "background",
stack: [
{Pleroma.Workers.BackgroundWorker, :perform, 2,
- [file: 'lib/pleroma/workers/background_worker.ex', line: 31]},
+ [file: ~c"lib/pleroma/workers/background_worker.ex", line: 31]},
{Oban.Queue.Executor, :safe_call, 1,
- [file: 'lib/oban/queue/executor.ex', line: 42]},
- {:timer, :tc, 3, [file: 'timer.erl', line: 197]},
- {Oban.Queue.Executor, :call, 2, [file: 'lib/oban/queue/executor.ex', line: 23]},
- {Task.Supervised, :invoke_mfa, 2, [file: 'lib/task/supervised.ex', line: 90]},
- {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 249]}
+ [file: ~c"lib/oban/queue/executor.ex", line: 42]},
+ {:timer, :tc, 3, [file: ~c"timer.erl", line: 197]},
+ {Oban.Queue.Executor, :call, 2, [file: ~c"lib/oban/queue/executor.ex", line: 23]},
+ {Task.Supervised, :invoke_mfa, 2, [file: ~c"lib/task/supervised.ex", line: 90]},
+ {:proc_lib, :init_p_do_apply, 3, [file: ~c"proc_lib.erl", line: 249]}
],
worker: "Pleroma.Workers.BackgroundWorker"
}}
diff --git a/test/pleroma/migration_helper/notification_backfill_test.exs b/test/pleroma/migration_helper/notification_backfill_test.exs
index 6d47bb6a8..2797cfb2c 100644
--- a/test/pleroma/migration_helper/notification_backfill_test.exs
+++ b/test/pleroma/migration_helper/notification_backfill_test.exs
@@ -21,7 +21,7 @@ defmodule Pleroma.MigrationHelper.NotificationBackfillTest do
{:ok, post} = CommonAPI.post(user, %{status: "yeah, @#{other_user.nickname}"})
{:ok, chat} = CommonAPI.post_chat_message(user, other_user, "yo")
{:ok, react} = CommonAPI.react_with_emoji(post.id, other_user, "☕")
- {:ok, like} = CommonAPI.favorite(other_user, post.id)
+ {:ok, like} = CommonAPI.favorite(post.id, other_user)
{:ok, react_2} = CommonAPI.react_with_emoji(post.id, other_user, "☕")
data =
diff --git a/test/pleroma/notification_test.exs b/test/pleroma/notification_test.exs
index 392fd53c2..e595c5c53 100644
--- a/test/pleroma/notification_test.exs
+++ b/test/pleroma/notification_test.exs
@@ -112,6 +112,7 @@ defmodule Pleroma.NotificationTest do
{:ok, [notification]} = Notification.create_notifications(status)
assert notification.user_id == subscriber.id
+ assert notification.type == "status"
end
test "does not create a notification for subscribed users if status is a reply" do
@@ -136,6 +137,21 @@ defmodule Pleroma.NotificationTest do
assert Enum.empty?(subscriber_notifications)
end
+ test "does not create subscriber notification if mentioned" do
+ user = insert(:user)
+ subscriber = insert(:user)
+
+ User.subscribe(subscriber, user)
+
+ {:ok, status} = CommonAPI.post(user, %{status: "mentioning @#{subscriber.nickname}"})
+ {:ok, [notification] = notifications} = Notification.create_notifications(status)
+
+ assert length(notifications) == 1
+
+ assert notification.user_id == subscriber.id
+ assert notification.type == "mention"
+ end
+
test "it sends edited notifications to those who repeated a status" do
user = insert(:user)
repeated_user = insert(:user)
@@ -149,7 +165,7 @@ defmodule Pleroma.NotificationTest do
{:ok, _activity_two} = CommonAPI.repeat(activity_one.id, repeated_user)
{:ok, _edit_activity} =
- CommonAPI.update(user, activity_one, %{
+ CommonAPI.update(activity_one, user, %{
status: "hey @#{other_user.nickname}! mew mew"
})
@@ -164,8 +180,8 @@ defmodule Pleroma.NotificationTest do
question = insert(:question, user: user1)
activity = insert(:question_activity, question: question)
- {:ok, _, _} = CommonAPI.vote(user2, question, [0])
- {:ok, _, _} = CommonAPI.vote(user3, question, [1])
+ {:ok, _, _} = CommonAPI.vote(question, user2, [0])
+ {:ok, _, _} = CommonAPI.vote(question, user3, [1])
{:ok, notifications} = Notification.create_poll_notifications(activity)
@@ -193,7 +209,7 @@ defmodule Pleroma.NotificationTest do
notification_settings: %Pleroma.User.NotificationSetting{block_from_strangers: true}
)
- CommonAPI.follow(follower, followed)
+ CommonAPI.follow(followed, follower)
{:ok, activity} = CommonAPI.post(follower, %{status: "hey @#{followed.nickname}"})
refute Notification.create_notification(activity, followed)
end
@@ -206,7 +222,7 @@ defmodule Pleroma.NotificationTest do
notification_settings: %Pleroma.User.NotificationSetting{block_from_strangers: true}
)
- CommonAPI.follow(receiver, poster)
+ CommonAPI.follow(poster, receiver)
{:ok, activity} = CommonAPI.post(poster, %{status: "hey @#{receiver.nickname}"})
assert Notification.create_notification(activity, receiver)
end
@@ -222,7 +238,7 @@ defmodule Pleroma.NotificationTest do
user = insert(:user)
subscriber = insert(:user)
- {:ok, _, _, _} = CommonAPI.follow(subscriber, user)
+ {:ok, _, _, _} = CommonAPI.follow(user, subscriber)
User.subscribe(subscriber, user)
{:ok, status} = CommonAPI.post(user, %{status: "Akariiiin"})
{:ok, [_notif]} = Notification.create_notifications(status)
@@ -279,7 +295,7 @@ defmodule Pleroma.NotificationTest do
insert(:filter, user: user, phrase: "tesla", hide: true)
{:ok, activity_one} = CommonAPI.post(user, %{status: "wow tesla"})
- {:ok, activity_two} = CommonAPI.favorite(other_user, activity_one.id)
+ {:ok, activity_two} = CommonAPI.favorite(activity_one.id, other_user)
{:ok, [notification]} = Notification.create_notifications(activity_two)
@@ -293,7 +309,7 @@ defmodule Pleroma.NotificationTest do
user = insert(:user)
followed_user = insert(:user, is_locked: false)
- {:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
+ {:ok, _, _, _activity} = CommonAPI.follow(followed_user, user)
assert FollowingRelationship.following?(user, followed_user)
assert [notification] = Notification.for_user(followed_user)
@@ -308,7 +324,7 @@ defmodule Pleroma.NotificationTest do
user = insert(:user)
followed_user = insert(:user, is_locked: true)
- {:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
+ {:ok, _, _, _activity} = CommonAPI.follow(followed_user, user)
refute FollowingRelationship.following?(user, followed_user)
assert [notification] = Notification.for_user(followed_user)
@@ -323,19 +339,22 @@ defmodule Pleroma.NotificationTest do
|> Repo.preload(:activity)
assert %{type: "follow"} =
- NotificationView.render("show.json", notification: notification, for: followed_user)
+ NotificationView.render("show.json",
+ notification: notification,
+ for: followed_user
+ )
end
test "it doesn't create a notification for follow-unfollow-follow chains" do
user = insert(:user)
followed_user = insert(:user, is_locked: false)
- {:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
+ {:ok, _, _, _activity} = CommonAPI.follow(followed_user, user)
assert FollowingRelationship.following?(user, followed_user)
assert [notification] = Notification.for_user(followed_user)
- CommonAPI.unfollow(user, followed_user)
- {:ok, _, _, _activity_dupe} = CommonAPI.follow(user, followed_user)
+ CommonAPI.unfollow(followed_user, user)
+ {:ok, _, _, _activity_dupe} = CommonAPI.follow(followed_user, user)
notification_id = notification.id
assert [%{id: ^notification_id}] = Notification.for_user(followed_user)
@@ -344,7 +363,7 @@ defmodule Pleroma.NotificationTest do
test "dismisses the notification on follow request rejection" do
user = insert(:user, is_locked: true)
follower = insert(:user)
- {:ok, _, _, _follow_activity} = CommonAPI.follow(follower, user)
+ {:ok, _, _, _follow_activity} = CommonAPI.follow(user, follower)
assert [_notification] = Notification.for_user(user)
{:ok, _follower} = CommonAPI.reject_follow_request(follower, user)
assert [] = Notification.for_user(user)
@@ -449,9 +468,7 @@ defmodule Pleroma.NotificationTest do
status: "hey yet again @#{other_user.nickname}!"
})
- [_, read_notification] = Notification.set_read_up_to(other_user, n2.id)
-
- assert read_notification.activity.object
+ Notification.set_read_up_to(other_user, n2.id)
[n3, n2, n1] = Notification.for_user(other_user)
@@ -600,7 +617,7 @@ defmodule Pleroma.NotificationTest do
status: "hey @#{other_user.nickname}!"
})
- {:ok, activity_two} = CommonAPI.favorite(third_user, activity_one.id)
+ {:ok, activity_two} = CommonAPI.favorite(activity_one.id, third_user)
enabled_receivers = Notification.get_notified_from_activity(activity_two)
@@ -676,7 +693,7 @@ defmodule Pleroma.NotificationTest do
{:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}!"})
- {:ok, _} = CommonAPI.add_mute(other_user, activity)
+ {:ok, _} = CommonAPI.add_mute(activity, other_user)
{:ok, same_context_activity} =
CommonAPI.post(user, %{
@@ -731,7 +748,7 @@ defmodule Pleroma.NotificationTest do
{:ok, _activity_two} = CommonAPI.repeat(activity_one.id, repeated_user)
{:ok, edit_activity} =
- CommonAPI.update(user, activity_one, %{
+ CommonAPI.update(activity_one, user, %{
status: "hey @#{other_user.nickname}! mew mew"
})
@@ -751,7 +768,7 @@ defmodule Pleroma.NotificationTest do
assert Enum.empty?(Notification.for_user(user))
- {:ok, _} = CommonAPI.favorite(other_user, activity.id)
+ {:ok, _} = CommonAPI.favorite(activity.id, other_user)
assert length(Notification.for_user(user)) == 1
@@ -768,7 +785,7 @@ defmodule Pleroma.NotificationTest do
assert Enum.empty?(Notification.for_user(user))
- {:ok, _} = CommonAPI.favorite(other_user, activity.id)
+ {:ok, _} = CommonAPI.favorite(activity.id, other_user)
assert length(Notification.for_user(user)) == 1
@@ -823,7 +840,7 @@ defmodule Pleroma.NotificationTest do
assert Enum.empty?(Notification.for_user(user))
- {:error, :not_found} = CommonAPI.favorite(other_user, activity.id)
+ {:error, :not_found} = CommonAPI.favorite(activity.id, other_user)
assert Enum.empty?(Notification.for_user(user))
end
@@ -845,22 +862,6 @@ defmodule Pleroma.NotificationTest do
assert Enum.empty?(Notification.for_user(user))
end
- test "replying to a deleted post without tagging does not generate a notification" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
- {:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
-
- {:ok, _reply_activity} =
- CommonAPI.post(other_user, %{
- status: "test reply",
- in_reply_to_status_id: activity.id
- })
-
- assert Enum.empty?(Notification.for_user(user))
- end
-
test "notifications are deleted if a local user is deleted" do
user = insert(:user)
other_user = insert(:user)
@@ -1089,7 +1090,7 @@ defmodule Pleroma.NotificationTest do
another_user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "Give me my cofe!"})
- {:ok, _} = CommonAPI.favorite(another_user, activity.id)
+ {:ok, _} = CommonAPI.favorite(activity.id, another_user)
assert length(Notification.for_user(user)) == 1
end
@@ -1100,7 +1101,7 @@ defmodule Pleroma.NotificationTest do
insert(:filter, user: followed_user, phrase: "test", hide: true)
- {:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
+ {:ok, _, _, _activity} = CommonAPI.follow(followed_user, user)
refute FollowingRelationship.following?(user, followed_user)
assert [notification] = Notification.for_user(followed_user)
diff --git a/test/pleroma/object/fetcher_test.exs b/test/pleroma/object/fetcher_test.exs
index 6f21452a7..6704c18db 100644
--- a/test/pleroma/object/fetcher_test.exs
+++ b/test/pleroma/object/fetcher_test.exs
@@ -84,7 +84,6 @@ defmodule Pleroma.Object.FetcherTest do
:ok
end
- @tag capture_log: true
test "it works when fetching the OP actor errors out" do
# Here we simulate a case where the author of the OP can't be read
assert {:ok, _} =
diff --git a/test/pleroma/object_test.exs b/test/pleroma/object_test.exs
index 2025d93e4..48d4d86eb 100644
--- a/test/pleroma/object_test.exs
+++ b/test/pleroma/object_test.exs
@@ -403,7 +403,7 @@ defmodule Pleroma.ObjectTest do
user = insert(:user)
activity = Activity.get_create_by_object_ap_id(object.data["id"])
- {:ok, activity} = CommonAPI.favorite(user, activity.id)
+ {:ok, activity} = CommonAPI.favorite(activity.id, user)
object = Object.get_by_ap_id(activity.data["object"])
assert object.data["like_count"] == 1
diff --git a/test/pleroma/resilience_test.exs b/test/pleroma/resilience_test.exs
index 9dc5d0dd6..0c4195fa8 100644
--- a/test/pleroma/resilience_test.exs
+++ b/test/pleroma/resilience_test.exs
@@ -18,7 +18,7 @@ defmodule Pleroma.ResilienceTest do
other_user = insert(:user)
{:ok, post_one} = CommonAPI.post(user, %{status: "Here is a post"})
- {:ok, like} = CommonAPI.favorite(other_user, post_one.id)
+ {:ok, like} = CommonAPI.favorite(post_one.id, other_user)
%{
user: user,
@@ -90,7 +90,7 @@ defmodule Pleroma.ResilienceTest do
|> json_response(200)
# Favoriting again doesn't hurt
- {:ok, _like_two} = CommonAPI.favorite(other_user, post.id)
+ {:ok, _like_two} = CommonAPI.favorite(post.id, other_user)
post = Repo.get(Activity, post.id)
diff --git a/test/pleroma/scheduled_activity_test.exs b/test/pleroma/scheduled_activity_test.exs
index 4818e8bcf..aaf643cfc 100644
--- a/test/pleroma/scheduled_activity_test.exs
+++ b/test/pleroma/scheduled_activity_test.exs
@@ -31,8 +31,7 @@ defmodule Pleroma.ScheduledActivityTest do
{:ok, sa1} = ScheduledActivity.create(user, attrs)
{:ok, sa2} = ScheduledActivity.create(user, attrs)
- jobs =
- Repo.all(from(j in Oban.Job, where: j.queue == "scheduled_activities", select: j.args))
+ jobs = Repo.all(from(j in Oban.Job, where: j.queue == "federator_outgoing", select: j.args))
assert jobs == [%{"activity_id" => sa1.id}, %{"activity_id" => sa2.id}]
end
diff --git a/test/pleroma/schema_test.exs b/test/pleroma/schema_test.exs
new file mode 100644
index 000000000..9bddd2031
--- /dev/null
+++ b/test/pleroma/schema_test.exs
@@ -0,0 +1,17 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.SchemaTest do
+ use Pleroma.DataCase, async: true
+
+ alias Pleroma.Repo
+
+ test "No unindexed foreign keys" do
+ query = File.read!("test/fixtures/unindexed_fk.sql")
+
+ {:ok, result} = Repo.query(query)
+
+ assert Enum.empty?(result.rows)
+ end
+end
diff --git a/test/pleroma/search/healthcheck_test.exs b/test/pleroma/search/healthcheck_test.exs
new file mode 100644
index 000000000..e7649d949
--- /dev/null
+++ b/test/pleroma/search/healthcheck_test.exs
@@ -0,0 +1,49 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2024 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Search.HealthcheckTest do
+ use Pleroma.DataCase
+
+ import Tesla.Mock
+
+ alias Pleroma.Search.Healthcheck
+
+ @good1 "http://good1.example.com/healthz"
+ @good2 "http://good2.example.com/health"
+ @bad "http://bad.example.com/healthy"
+
+ setup do
+ mock(fn
+ %{method: :get, url: @good1} ->
+ %Tesla.Env{
+ status: 200,
+ body: ""
+ }
+
+ %{method: :get, url: @good2} ->
+ %Tesla.Env{
+ status: 200,
+ body: ""
+ }
+
+ %{method: :get, url: @bad} ->
+ %Tesla.Env{
+ status: 503,
+ body: ""
+ }
+ end)
+
+ :ok
+ end
+
+ test "true for 200 responses" do
+ assert Healthcheck.check([@good1])
+ assert Healthcheck.check([@good1, @good2])
+ end
+
+ test "false if any response is not a 200" do
+ refute Healthcheck.check([@bad])
+ refute Healthcheck.check([@good1, @bad])
+ end
+end
diff --git a/test/pleroma/search/qdrant_search_test.exs b/test/pleroma/search/qdrant_search_test.exs
new file mode 100644
index 000000000..47a77a391
--- /dev/null
+++ b/test/pleroma/search/qdrant_search_test.exs
@@ -0,0 +1,199 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Search.QdrantSearchTest do
+ use Pleroma.DataCase, async: true
+ use Oban.Testing, repo: Pleroma.Repo
+
+ import Pleroma.Factory
+ import Mox
+
+ alias Pleroma.Search.QdrantSearch
+ alias Pleroma.UnstubbedConfigMock, as: Config
+ alias Pleroma.Web.CommonAPI
+ alias Pleroma.Workers.SearchIndexingWorker
+
+ describe "Qdrant search" do
+ test "returns the correct healthcheck endpoints" do
+ # No openai healthcheck URL
+ Config
+ |> expect(:get, 2, fn
+ [Pleroma.Search.QdrantSearch, key], nil ->
+ %{qdrant_url: "https://qdrant.url"}[key]
+ end)
+
+ [health_endpoint] = QdrantSearch.healthcheck_endpoints()
+
+ assert "https://qdrant.url/healthz" == health_endpoint
+
+ # Set openai healthcheck URL
+ Config
+ |> expect(:get, 2, fn
+ [Pleroma.Search.QdrantSearch, key], nil ->
+ %{qdrant_url: "https://qdrant.url", openai_healthcheck_url: "https://openai.url/health"}[
+ key
+ ]
+ end)
+
+ [_, health_endpoint] = QdrantSearch.healthcheck_endpoints()
+
+ assert "https://openai.url/health" == health_endpoint
+ end
+
+ test "searches for a term by encoding it and sending it to qdrant" do
+ user = insert(:user)
+
+ {:ok, activity} =
+ CommonAPI.post(user, %{
+ status: "guys i just don't wanna leave the swamp",
+ visibility: "public"
+ })
+
+ Config
+ |> expect(:get, 3, fn
+ [Pleroma.Search, :module], nil ->
+ QdrantSearch
+
+ [Pleroma.Search.QdrantSearch, key], nil ->
+ %{
+ openai_model: "a_model",
+ openai_url: "https://openai.url",
+ qdrant_url: "https://qdrant.url"
+ }[key]
+ end)
+
+ Tesla.Mock.mock(fn
+ %{url: "https://openai.url/v1/embeddings", method: :post} ->
+ Tesla.Mock.json(%{
+ data: [%{embedding: [1, 2, 3]}]
+ })
+
+ %{url: "https://qdrant.url/collections/posts/points/search", method: :post, body: body} ->
+ data = Jason.decode!(body)
+ refute data["filter"]
+
+ Tesla.Mock.json(%{
+ result: [%{"id" => activity.id |> FlakeId.from_string() |> Ecto.UUID.cast!()}]
+ })
+ end)
+
+ results = QdrantSearch.search(nil, "guys i just don't wanna leave the swamp", %{})
+
+ assert results == [activity]
+ end
+
+ test "for a given actor, ask for only relevant matches" do
+ user = insert(:user)
+
+ {:ok, activity} =
+ CommonAPI.post(user, %{
+ status: "guys i just don't wanna leave the swamp",
+ visibility: "public"
+ })
+
+ Config
+ |> expect(:get, 3, fn
+ [Pleroma.Search, :module], nil ->
+ QdrantSearch
+
+ [Pleroma.Search.QdrantSearch, key], nil ->
+ %{
+ openai_model: "a_model",
+ openai_url: "https://openai.url",
+ qdrant_url: "https://qdrant.url"
+ }[key]
+ end)
+
+ Tesla.Mock.mock(fn
+ %{url: "https://openai.url/v1/embeddings", method: :post} ->
+ Tesla.Mock.json(%{
+ data: [%{embedding: [1, 2, 3]}]
+ })
+
+ %{url: "https://qdrant.url/collections/posts/points/search", method: :post, body: body} ->
+ data = Jason.decode!(body)
+
+ assert data["filter"] == %{
+ "must" => [%{"key" => "actor", "match" => %{"value" => user.ap_id}}]
+ }
+
+ Tesla.Mock.json(%{
+ result: [%{"id" => activity.id |> FlakeId.from_string() |> Ecto.UUID.cast!()}]
+ })
+ end)
+
+ results =
+ QdrantSearch.search(nil, "guys i just don't wanna leave the swamp", %{author: user})
+
+ assert results == [activity]
+ end
+
+ test "indexes a public post on creation, deletes from the index on deletion" do
+ user = insert(:user)
+
+ Tesla.Mock.mock(fn
+ %{method: :post, url: "https://openai.url/v1/embeddings"} ->
+ send(self(), "posted_to_openai")
+
+ Tesla.Mock.json(%{
+ data: [%{embedding: [1, 2, 3]}]
+ })
+
+ %{method: :put, url: "https://qdrant.url/collections/posts/points", body: body} ->
+ send(self(), "posted_to_qdrant")
+
+ data = Jason.decode!(body)
+ %{"points" => [%{"vector" => vector, "payload" => payload}]} = data
+
+ assert vector == [1, 2, 3]
+ assert payload["actor"]
+ assert payload["published_at"]
+
+ Tesla.Mock.json("ok")
+
+ %{method: :post, url: "https://qdrant.url/collections/posts/points/delete"} ->
+ send(self(), "deleted_from_qdrant")
+ Tesla.Mock.json("ok")
+ end)
+
+ Config
+ |> expect(:get, 6, fn
+ [Pleroma.Search, :module], nil ->
+ QdrantSearch
+
+ [Pleroma.Search.QdrantSearch, key], nil ->
+ %{
+ openai_model: "a_model",
+ openai_url: "https://openai.url",
+ qdrant_url: "https://qdrant.url"
+ }[key]
+ end)
+
+ {:ok, activity} =
+ CommonAPI.post(user, %{
+ status: "guys i just don't wanna leave the swamp",
+ visibility: "public"
+ })
+
+ args = %{"op" => "add_to_index", "activity" => activity.id}
+
+ assert_enqueued(
+ worker: SearchIndexingWorker,
+ args: args
+ )
+
+ assert :ok = perform_job(SearchIndexingWorker, args)
+ assert_received("posted_to_openai")
+ assert_received("posted_to_qdrant")
+
+ {:ok, _} = CommonAPI.delete(activity.id, user)
+
+ delete_args = %{"op" => "remove_from_index", "object" => activity.object.id}
+ assert_enqueued(worker: SearchIndexingWorker, args: delete_args)
+ assert :ok = perform_job(SearchIndexingWorker, delete_args)
+
+ assert_received("deleted_from_qdrant")
+ end
+ end
+end
diff --git a/test/pleroma/signature_test.exs b/test/pleroma/signature_test.exs
index 8edf67a7b..572d7acc3 100644
--- a/test/pleroma/signature_test.exs
+++ b/test/pleroma/signature_test.exs
@@ -67,6 +67,14 @@ defmodule Pleroma.SignatureTest do
end
end
+ describe "get_actor_id/1" do
+ test "it returns actor id" do
+ ap_id = "https://mastodon.social/users/lambadalambda"
+
+ assert Signature.get_actor_id(make_fake_conn(ap_id)) == {:ok, ap_id}
+ end
+ end
+
describe "sign/2" do
test "it returns signature headers" do
user =
diff --git a/test/pleroma/stats_test.exs b/test/pleroma/stats_test.exs
index 37a085afc..c70603ab9 100644
--- a/test/pleroma/stats_test.exs
+++ b/test/pleroma/stats_test.exs
@@ -73,8 +73,8 @@ defmodule Pleroma.StatsTest do
user = insert(:user)
other_user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{visibility: "public", status: "hey"})
- _ = CommonAPI.follow(user, other_user)
- CommonAPI.favorite(other_user, activity.id)
+ _ = CommonAPI.follow(other_user, user)
+ CommonAPI.favorite(activity.id, other_user)
CommonAPI.repeat(activity.id, other_user)
assert %{"direct" => 0, "private" => 0, "public" => 1, "unlisted" => 0} =
diff --git a/test/pleroma/upload/filter/exiftool/strip_location_test.exs b/test/pleroma/upload/filter/exiftool/strip_location_test.exs
index bcb5f3f60..4dcd4dce3 100644
--- a/test/pleroma/upload/filter/exiftool/strip_location_test.exs
+++ b/test/pleroma/upload/filter/exiftool/strip_location_test.exs
@@ -9,29 +9,31 @@ defmodule Pleroma.Upload.Filter.Exiftool.StripLocationTest do
test "apply exiftool filter" do
assert Pleroma.Utils.command_available?("exiftool")
- File.cp!(
- "test/fixtures/DSCN0010.jpg",
- "test/fixtures/DSCN0010_tmp.jpg"
- )
-
- upload = %Pleroma.Upload{
- name: "image_with_GPS_data.jpg",
- content_type: "image/jpeg",
- path: Path.absname("test/fixtures/DSCN0010.jpg"),
- tempfile: Path.absname("test/fixtures/DSCN0010_tmp.jpg")
- }
-
- assert Filter.Exiftool.StripLocation.filter(upload) == {:ok, :filtered}
-
- {exif_original, 0} = System.cmd("exiftool", ["test/fixtures/DSCN0010.jpg"])
- {exif_filtered, 0} = System.cmd("exiftool", ["test/fixtures/DSCN0010_tmp.jpg"])
-
- refute exif_original == exif_filtered
- assert String.match?(exif_original, ~r/GPS/)
- refute String.match?(exif_filtered, ~r/GPS/)
+ ~w{jpg png}
+ |> Enum.map(fn type ->
+ File.cp!(
+ "test/fixtures/DSCN0010.#{type}",
+ "test/fixtures/DSCN0010_tmp.#{type}"
+ )
+
+ upload = %Pleroma.Upload{
+ name: "image_with_GPS_data.#{type}",
+ content_type: "image/jpeg",
+ path: Path.absname("test/fixtures/DSCN0010.#{type}"),
+ tempfile: Path.absname("test/fixtures/DSCN0010_tmp.#{type}")
+ }
+
+ assert Filter.Exiftool.StripLocation.filter(upload) == {:ok, :filtered}
+
+ {exif_original, 0} = System.cmd("exiftool", ["test/fixtures/DSCN0010.#{type}"])
+ {exif_filtered, 0} = System.cmd("exiftool", ["test/fixtures/DSCN0010_tmp.#{type}"])
+
+ assert String.match?(exif_original, ~r/GPS/)
+ refute String.match?(exif_filtered, ~r/GPS/)
+ end)
end
- test "verify webp, heic, svg files are skipped" do
+ test "verify webp, heic, svg files are skipped" do
uploads =
~w{webp heic svg svg+xml}
|> Enum.map(fn type ->
diff --git a/test/pleroma/uploaders/ipfs_test.exs b/test/pleroma/uploaders/ipfs_test.exs
new file mode 100644
index 000000000..bdf2933ac
--- /dev/null
+++ b/test/pleroma/uploaders/ipfs_test.exs
@@ -0,0 +1,155 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Uploaders.IPFSTest do
+ use Pleroma.DataCase
+
+ alias Pleroma.Uploaders.IPFS
+ alias Tesla.Multipart
+
+ import ExUnit.CaptureLog
+ import Mock
+ import Mox
+
+ alias Pleroma.UnstubbedConfigMock, as: Config
+
+ describe "get_file/1" do
+ setup do
+ Config
+ |> expect(:get, fn [Pleroma.Upload, :uploader] -> Pleroma.Uploaders.IPFS end)
+ |> expect(:get, fn [Pleroma.Upload, :base_url] -> nil end)
+ |> expect(:get, fn [Pleroma.Uploaders.IPFS, :public_endpoint] -> nil end)
+
+ :ok
+ end
+
+ test "it returns path to ipfs file with cid as subdomain" do
+ Config
+ |> expect(:get, fn [Pleroma.Uploaders.IPFS, :get_gateway_url] ->
+ "https://{CID}.ipfs.mydomain.com"
+ end)
+
+ assert IPFS.get_file("testcid") == {
+ :ok,
+ {:url, "https://testcid.ipfs.mydomain.com"}
+ }
+ end
+
+ test "it returns path to ipfs file with cid as path" do
+ Config
+ |> expect(:get, fn [Pleroma.Uploaders.IPFS, :get_gateway_url] ->
+ "https://ipfs.mydomain.com/ipfs/{CID}"
+ end)
+
+ assert IPFS.get_file("testcid") == {
+ :ok,
+ {:url, "https://ipfs.mydomain.com/ipfs/testcid"}
+ }
+ end
+ end
+
+ describe "put_file/1" do
+ setup do
+ Config
+ |> expect(:get, fn [Pleroma.Uploaders.IPFS, :post_gateway_url] ->
+ "http://localhost:5001"
+ end)
+
+ file_upload = %Pleroma.Upload{
+ name: "image-tet.jpg",
+ content_type: "image/jpeg",
+ path: "test_folder/image-tet.jpg",
+ tempfile: Path.absname("test/instance_static/add/shortcode.png")
+ }
+
+ mp =
+ Multipart.new()
+ |> Multipart.add_content_type_param("charset=utf-8")
+ |> Multipart.add_file(file_upload.tempfile)
+
+ [file_upload: file_upload, mp: mp]
+ end
+
+ test "save file", %{file_upload: file_upload} do
+ with_mock Pleroma.HTTP,
+ post: fn "http://localhost:5001/api/v0/add",
+ _mp,
+ [],
+ params: ["cid-version": "1"],
+ pool: :upload ->
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body:
+ "{\"Name\":\"image-tet.jpg\",\"Size\":\"5000\", \"Hash\":\"bafybeicrh7ltzx52yxcwrvxxckfmwhqdgsb6qym6dxqm2a4ymsakeshwoi\"}"
+ }}
+ end do
+ assert IPFS.put_file(file_upload) ==
+ {:ok, {:file, "bafybeicrh7ltzx52yxcwrvxxckfmwhqdgsb6qym6dxqm2a4ymsakeshwoi"}}
+ end
+ end
+
+ test "returns error", %{file_upload: file_upload} do
+ with_mock Pleroma.HTTP,
+ post: fn "http://localhost:5001/api/v0/add",
+ _mp,
+ [],
+ params: ["cid-version": "1"],
+ pool: :upload ->
+ {:error, "IPFS Gateway upload failed"}
+ end do
+ assert capture_log(fn ->
+ assert IPFS.put_file(file_upload) == {:error, "IPFS Gateway upload failed"}
+ end) =~ "Elixir.Pleroma.Uploaders.IPFS: {:error, \"IPFS Gateway upload failed\"}"
+ end
+ end
+
+ test "returns error if JSON decode fails", %{file_upload: file_upload} do
+ with_mock Pleroma.HTTP, [],
+ post: fn "http://localhost:5001/api/v0/add",
+ _mp,
+ [],
+ params: ["cid-version": "1"],
+ pool: :upload ->
+ {:ok, %Tesla.Env{status: 200, body: "invalid"}}
+ end do
+ assert capture_log(fn ->
+ assert IPFS.put_file(file_upload) == {:error, "JSON decode failed"}
+ end) =~
+ "Elixir.Pleroma.Uploaders.IPFS: {:error, %Jason.DecodeError"
+ end
+ end
+
+ test "returns error if JSON body doesn't contain Hash key", %{file_upload: file_upload} do
+ with_mock Pleroma.HTTP, [],
+ post: fn "http://localhost:5001/api/v0/add",
+ _mp,
+ [],
+ params: ["cid-version": "1"],
+ pool: :upload ->
+ {:ok, %Tesla.Env{status: 200, body: "{\"key\": \"value\"}"}}
+ end do
+ assert IPFS.put_file(file_upload) == {:error, "JSON doesn't contain Hash key"}
+ end
+ end
+ end
+
+ describe "delete_file/1" do
+ setup do
+ Config
+ |> expect(:get, fn [Pleroma.Uploaders.IPFS, :post_gateway_url] ->
+ "http://localhost:5001"
+ end)
+
+ :ok
+ end
+
+ test_with_mock "deletes file", Pleroma.HTTP,
+ post: fn "http://localhost:5001/api/v0/files/rm", "", [], params: [arg: "image.jpg"] ->
+ {:ok, %{status: 204}}
+ end do
+ assert :ok = IPFS.delete_file("image.jpg")
+ end
+ end
+end
diff --git a/test/pleroma/user/backup_async_test.exs b/test/pleroma/user/backup_async_test.exs
index 76716d684..b0e9413be 100644
--- a/test/pleroma/user/backup_async_test.exs
+++ b/test/pleroma/user/backup_async_test.exs
@@ -19,7 +19,6 @@ defmodule Pleroma.User.BackupAsyncTest do
%{backup: backup}
end
- @tag capture_log: true
test "it handles unrecoverable exceptions", %{backup: backup} do
ProcessorMock
|> expect(:do_process, fn _, _ ->
@@ -34,7 +33,6 @@ defmodule Pleroma.User.BackupAsyncTest do
assert backup.state == :failed
end
- @tag capture_log: true
test "it handles timeouts", %{backup: backup} do
ProcessorMock
|> expect(:do_process, fn _, _ ->
diff --git a/test/pleroma/user/backup_test.exs b/test/pleroma/user/backup_test.exs
index 5503d15bc..d82d1719b 100644
--- a/test/pleroma/user/backup_test.exs
+++ b/test/pleroma/user/backup_test.exs
@@ -177,18 +177,18 @@ defmodule Pleroma.User.BackupTest do
{:ok, %{object: %{data: %{"id" => id3}}} = status3} =
CommonAPI.post(user, %{status: "status3"})
- CommonAPI.favorite(user, status1.id)
- CommonAPI.favorite(user, status2.id)
+ CommonAPI.favorite(status1.id, user)
+ CommonAPI.favorite(status2.id, user)
Bookmark.create(user.id, status2.id)
Bookmark.create(user.id, status3.id)
- CommonAPI.follow(user, other_user)
+ CommonAPI.follow(other_user, user)
assert {:ok, backup} = user |> Backup.new() |> Repo.insert()
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)
+ assert {:ok, {~c"actor.json", json}} = :zip.zip_get(~c"actor.json", zipfile)
assert %{
"@context" => [
@@ -213,7 +213,7 @@ defmodule Pleroma.User.BackupTest do
"url" => "http://cofe.io/users/cofe"
} = Jason.decode!(json)
- assert {:ok, {'outbox.json', json}} = :zip.zip_get('outbox.json', zipfile)
+ assert {:ok, {~c"outbox.json", json}} = :zip.zip_get(~c"outbox.json", zipfile)
assert %{
"@context" => "https://www.w3.org/ns/activitystreams",
@@ -244,7 +244,7 @@ defmodule Pleroma.User.BackupTest do
"type" => "OrderedCollection"
} = Jason.decode!(json)
- assert {:ok, {'likes.json', json}} = :zip.zip_get('likes.json', zipfile)
+ assert {:ok, {~c"likes.json", json}} = :zip.zip_get(~c"likes.json", zipfile)
assert %{
"@context" => "https://www.w3.org/ns/activitystreams",
@@ -254,7 +254,7 @@ defmodule Pleroma.User.BackupTest do
"type" => "OrderedCollection"
} = Jason.decode!(json)
- assert {:ok, {'bookmarks.json', json}} = :zip.zip_get('bookmarks.json', zipfile)
+ assert {:ok, {~c"bookmarks.json", json}} = :zip.zip_get(~c"bookmarks.json", zipfile)
assert %{
"@context" => "https://www.w3.org/ns/activitystreams",
@@ -264,7 +264,7 @@ defmodule Pleroma.User.BackupTest do
"type" => "OrderedCollection"
} = Jason.decode!(json)
- assert {:ok, {'following.json', json}} = :zip.zip_get('following.json', zipfile)
+ assert {:ok, {~c"following.json", json}} = :zip.zip_get(~c"following.json", zipfile)
assert %{
"@context" => "https://www.w3.org/ns/activitystreams",
@@ -283,7 +283,7 @@ defmodule Pleroma.User.BackupTest do
Enum.map(1..120, fn i ->
{:ok, status} = CommonAPI.post(user, %{status: "status #{i}"})
- CommonAPI.favorite(user, status.id)
+ CommonAPI.favorite(status.id, user)
Bookmark.create(user.id, status.id)
end)
@@ -337,8 +337,8 @@ defmodule Pleroma.User.BackupTest do
{:ok, status1} = CommonAPI.post(user, %{status: "status1"})
{:ok, status2} = CommonAPI.post(user, %{status: "status2"})
{:ok, status3} = CommonAPI.post(user, %{status: "status3"})
- CommonAPI.favorite(user, status1.id)
- CommonAPI.favorite(user, status2.id)
+ CommonAPI.favorite(status1.id, user)
+ CommonAPI.favorite(status2.id, user)
Bookmark.create(user.id, status2.id)
Bookmark.create(user.id, status3.id)
diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs
index a93f81659..036ae78fb 100644
--- a/test/pleroma/user_test.exs
+++ b/test/pleroma/user_test.exs
@@ -182,8 +182,8 @@ defmodule Pleroma.UserTest do
locked = insert(:user, is_locked: true)
follower = insert(:user)
- CommonAPI.follow(follower, unlocked)
- CommonAPI.follow(follower, locked)
+ CommonAPI.follow(unlocked, follower)
+ CommonAPI.follow(locked, follower)
assert [] = User.get_follow_requests(unlocked)
assert [activity] = User.get_follow_requests(locked)
@@ -196,9 +196,9 @@ defmodule Pleroma.UserTest do
pending_follower = insert(:user)
accepted_follower = insert(:user)
- CommonAPI.follow(pending_follower, locked)
- CommonAPI.follow(pending_follower, locked)
- CommonAPI.follow(accepted_follower, locked)
+ CommonAPI.follow(locked, pending_follower)
+ CommonAPI.follow(locked, pending_follower)
+ CommonAPI.follow(locked, accepted_follower)
Pleroma.FollowingRelationship.update(accepted_follower, locked, :follow_accept)
@@ -209,7 +209,7 @@ defmodule Pleroma.UserTest do
locked = insert(:user, is_locked: true)
pending_follower = insert(:user, %{is_active: false})
- CommonAPI.follow(pending_follower, locked)
+ CommonAPI.follow(locked, pending_follower)
refute pending_follower.is_active
assert [] = User.get_follow_requests(locked)
@@ -219,7 +219,7 @@ defmodule Pleroma.UserTest do
followed = insert(:user, is_locked: true)
follower = insert(:user)
- CommonAPI.follow(follower, followed)
+ CommonAPI.follow(followed, follower)
assert [_activity] = User.get_follow_requests(followed)
{:ok, _user_relationship} = User.block(followed, follower)
@@ -877,109 +877,19 @@ defmodule Pleroma.UserTest do
setup do: clear_config([Pleroma.Web.WebFinger, :update_nickname_on_user_fetch], true)
test "for mastodon" do
- Tesla.Mock.mock(fn
- %{url: "https://example.com/.well-known/host-meta"} ->
- %Tesla.Env{
- status: 302,
- headers: [{"location", "https://sub.example.com/.well-known/host-meta"}]
- }
-
- %{url: "https://sub.example.com/.well-known/host-meta"} ->
- %Tesla.Env{
- status: 200,
- body:
- "test/fixtures/webfinger/masto-host-meta.xml"
- |> File.read!()
- |> String.replace("{{domain}}", "sub.example.com")
- }
-
- %{url: "https://sub.example.com/.well-known/webfinger?resource=acct:a@example.com"} ->
- %Tesla.Env{
- status: 200,
- body:
- "test/fixtures/webfinger/masto-webfinger.json"
- |> File.read!()
- |> String.replace("{{nickname}}", "a")
- |> String.replace("{{domain}}", "example.com")
- |> String.replace("{{subdomain}}", "sub.example.com"),
- headers: [{"content-type", "application/jrd+json"}]
- }
-
- %{url: "https://sub.example.com/users/a"} ->
- %Tesla.Env{
- status: 200,
- body:
- "test/fixtures/webfinger/masto-user.json"
- |> File.read!()
- |> String.replace("{{nickname}}", "a")
- |> String.replace("{{domain}}", "sub.example.com"),
- headers: [{"content-type", "application/activity+json"}]
- }
-
- %{url: "https://sub.example.com/users/a/collections/featured"} ->
- %Tesla.Env{
- status: 200,
- body:
- File.read!("test/fixtures/users_mock/masto_featured.json")
- |> String.replace("{{domain}}", "sub.example.com")
- |> String.replace("{{nickname}}", "a"),
- headers: [{"content-type", "application/activity+json"}]
- }
- end)
-
- ap_id = "a@example.com"
+ ap_id = "a@mastodon.example"
{:ok, fetched_user} = User.get_or_fetch(ap_id)
- assert fetched_user.ap_id == "https://sub.example.com/users/a"
- assert fetched_user.nickname == "a@example.com"
+ assert fetched_user.ap_id == "https://sub.mastodon.example/users/a"
+ assert fetched_user.nickname == "a@mastodon.example"
end
test "for pleroma" do
- Tesla.Mock.mock(fn
- %{url: "https://example.com/.well-known/host-meta"} ->
- %Tesla.Env{
- status: 302,
- headers: [{"location", "https://sub.example.com/.well-known/host-meta"}]
- }
-
- %{url: "https://sub.example.com/.well-known/host-meta"} ->
- %Tesla.Env{
- status: 200,
- body:
- "test/fixtures/webfinger/pleroma-host-meta.xml"
- |> File.read!()
- |> String.replace("{{domain}}", "sub.example.com")
- }
-
- %{url: "https://sub.example.com/.well-known/webfinger?resource=acct:a@example.com"} ->
- %Tesla.Env{
- status: 200,
- body:
- "test/fixtures/webfinger/pleroma-webfinger.json"
- |> File.read!()
- |> String.replace("{{nickname}}", "a")
- |> String.replace("{{domain}}", "example.com")
- |> String.replace("{{subdomain}}", "sub.example.com"),
- headers: [{"content-type", "application/jrd+json"}]
- }
-
- %{url: "https://sub.example.com/users/a"} ->
- %Tesla.Env{
- status: 200,
- body:
- "test/fixtures/webfinger/pleroma-user.json"
- |> File.read!()
- |> String.replace("{{nickname}}", "a")
- |> String.replace("{{domain}}", "sub.example.com"),
- headers: [{"content-type", "application/activity+json"}]
- }
- end)
-
- ap_id = "a@example.com"
+ ap_id = "a@pleroma.example"
{:ok, fetched_user} = User.get_or_fetch(ap_id)
- assert fetched_user.ap_id == "https://sub.example.com/users/a"
- assert fetched_user.nickname == "a@example.com"
+ assert fetched_user.ap_id == "https://sub.pleroma.example/users/a"
+ assert fetched_user.nickname == "a@pleroma.example"
end
end
@@ -1016,7 +926,6 @@ defmodule Pleroma.UserTest do
assert user == fetched_user
end
- @tag capture_log: true
test "returns nil if no user could be fetched" do
{:error, fetched_user} = User.get_or_fetch_by_nickname("nonexistent@social.heldscal.la")
assert fetched_user == "not found nonexistent@social.heldscal.la"
@@ -1043,9 +952,16 @@ defmodule Pleroma.UserTest do
{:ok, user} = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/admin")
- assert user.inbox
+ # Oban job was generated to refresh the stale user
+ assert_enqueued(worker: "Pleroma.Workers.UserRefreshWorker", args: %{"ap_id" => user.ap_id})
+
+ # Run job to refresh the user; just capture its output instead of fetching it again
+ assert {:ok, updated_user} =
+ perform_job(Pleroma.Workers.UserRefreshWorker, %{"ap_id" => user.ap_id})
+
+ assert updated_user.inbox
- refute user.last_refreshed_at == orig_user.last_refreshed_at
+ refute updated_user.last_refreshed_at == orig_user.last_refreshed_at
end
test "if nicknames clash, the old user gets a prefix with the old id to the nickname" do
@@ -1073,7 +989,6 @@ defmodule Pleroma.UserTest do
assert orig_user.nickname == "#{orig_user.id}.admin@mastodon.example.org"
end
- @tag capture_log: true
test "it returns the old user if stale, but unfetchable" do
a_week_ago = NaiveDateTime.add(NaiveDateTime.utc_now(), -604_800)
@@ -1611,7 +1526,7 @@ defmodule Pleroma.UserTest do
assert [activity] == ActivityPub.fetch_public_activities(%{}) |> Repo.preload(:bookmark)
- assert [%{activity | thread_muted?: CommonAPI.thread_muted?(user2, activity)}] ==
+ assert [%{activity | thread_muted?: CommonAPI.thread_muted?(activity, user2)}] ==
ActivityPub.fetch_activities([user2.ap_id | User.following(user2)], %{
user: user2
})
@@ -1776,8 +1691,8 @@ defmodule Pleroma.UserTest do
object_two = insert(:note, user: follower)
activity_two = insert(:note_activity, user: follower, note: object_two)
- {:ok, like} = CommonAPI.favorite(user, activity_two.id)
- {:ok, like_two} = CommonAPI.favorite(follower, activity.id)
+ {:ok, like} = CommonAPI.favorite(activity_two.id, user)
+ {:ok, like_two} = CommonAPI.favorite(activity.id, follower)
{:ok, repeat} = CommonAPI.repeat(activity_two.id, user)
{:ok, job} = User.delete(user)
@@ -2894,6 +2809,20 @@ defmodule Pleroma.UserTest do
end
end
+ describe "get_familiar_followers/3" do
+ test "returns familiar followers for a pair of users" do
+ user1 = insert(:user)
+ %{id: id2} = user2 = insert(:user)
+ user3 = insert(:user)
+ _user4 = insert(:user)
+
+ User.follow(user1, user2)
+ User.follow(user2, user3)
+
+ assert [%{id: ^id2}] = User.get_familiar_followers(user3, user1)
+ end
+ end
+
describe "account endorsements" do
test "it pins people" do
user = insert(:user)
diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
index ec4c04c62..6aae61835 100644
--- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
+++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
@@ -573,7 +573,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert Activity.get_by_ap_id(data["id"])
end
- @tag capture_log: true
test "it inserts an incoming activity into the database" <>
"even if we can't fetch the user but have it in our db",
%{conn: conn} do
@@ -657,7 +656,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert_receive {:mix_shell, :info, ["https://relay.mastodon.host/actor"]}
end
- @tag capture_log: true
test "without valid signature, " <>
"it only accepts Create activities and requires enabled federation",
%{conn: conn} do
@@ -1080,7 +1078,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert Instances.reachable?(sender_host)
end
- @tag capture_log: true
test "it removes all follower collections but actor's", %{conn: conn} do
[actor, recipient] = insert_pair(:user)
@@ -1143,7 +1140,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert json_response(ret_conn, 200)
end
- @tag capture_log: true
test "forwarded report", %{conn: conn} do
admin = insert(:user, is_admin: true)
actor = insert(:user, local: false)
@@ -1219,7 +1215,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
)
end
- @tag capture_log: true
test "forwarded report from mastodon", %{conn: conn} do
admin = insert(:user, is_admin: true)
actor = insert(:user, local: false)
@@ -1229,7 +1224,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
note = insert(:note_activity, user: reported_user)
- Pleroma.Web.CommonAPI.favorite(another, note.id)
+ Pleroma.Web.CommonAPI.favorite(note.id, another)
mock_json_body =
"test/fixtures/mastodon/application_actor.json"
@@ -1407,7 +1402,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert question = Object.normalize(activity, fetch: false)
- {:ok, [activity], _object} = CommonAPI.vote(voter, question, [1])
+ {:ok, [activity], _object} = CommonAPI.vote(question, voter, [1])
assert outbox_get =
conn
@@ -1752,7 +1747,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
%{conn: conn} do
user = insert(:user, hide_followers: true)
other_user = insert(:user)
- {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
+ {:ok, _other_user, user, _activity} = CommonAPI.follow(user, other_user)
result =
conn
@@ -1848,7 +1843,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
%{conn: conn} do
user = insert(:user, hide_follows: true)
other_user = insert(:user)
- {:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)
+ {:ok, user, _other_user, _activity} = CommonAPI.follow(other_user, user)
result =
conn
diff --git a/test/pleroma/web/activity_pub/activity_pub_test.exs b/test/pleroma/web/activity_pub/activity_pub_test.exs
index 524294385..b4f6fb68a 100644
--- a/test/pleroma/web/activity_pub/activity_pub_test.exs
+++ b/test/pleroma/web/activity_pub/activity_pub_test.exs
@@ -291,9 +291,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
body: featured_data,
headers: [{"content-type", "application/activity+json"}]
}
- end)
- Tesla.Mock.mock_global(fn
%{
method: :get,
url: ^object_url
@@ -306,7 +304,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
end)
{:ok, user} = ActivityPub.make_user_from_ap_id(ap_id)
- Process.sleep(50)
+
+ assert_enqueued(
+ worker: Pleroma.Workers.RemoteFetcherWorker,
+ args: %{
+ "op" => "fetch_remote",
+ "id" => object_url,
+ "depth" => 1
+ }
+ )
+
+ # wait for oban
+ Pleroma.Tests.ObanHelpers.perform_all()
assert user.featured_address == featured_url
assert Map.has_key?(user.pinned_objects, object_url)
@@ -368,9 +377,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
body: featured_data,
headers: [{"content-type", "application/activity+json"}]
}
- end)
- Tesla.Mock.mock_global(fn
%{
method: :get,
url: ^object_url
@@ -383,7 +390,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
end)
{:ok, user} = ActivityPub.make_user_from_ap_id(ap_id)
- Process.sleep(50)
+
+ assert_enqueued(
+ worker: Pleroma.Workers.RemoteFetcherWorker,
+ args: %{
+ "op" => "fetch_remote",
+ "id" => object_url,
+ "depth" => 1
+ }
+ )
+
+ # wait for oban
+ Pleroma.Tests.ObanHelpers.perform_all()
assert user.featured_address == featured_url
assert Map.has_key?(user.pinned_objects, object_url)
@@ -1020,7 +1038,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
refute activity in activities
followed_user = insert(:user)
- CommonAPI.follow(user, followed_user)
+ CommonAPI.follow(followed_user, user)
{:ok, repeat_activity} = CommonAPI.repeat(activity.id, followed_user)
activities = ActivityPub.fetch_activities([], %{blocking_user: user, skip_preload: true})
@@ -1153,7 +1171,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
note_two = insert(:note, data: %{"context" => "suya.."})
activity_two = insert(:note_activity, note: note_two)
- {:ok, _activity_two} = CommonAPI.add_mute(user, activity_two)
+ {:ok, _activity_two} = CommonAPI.add_mute(activity_two, user)
assert [_activity_one] = ActivityPub.fetch_activities([], %{muting_user: user})
end
@@ -1164,7 +1182,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
note_two = insert(:note, data: %{"context" => "suya.."})
activity_two = insert(:note_activity, note: note_two)
- {:ok, _activity_two} = CommonAPI.add_mute(user, activity_two)
+ {:ok, _activity_two} = CommonAPI.add_mute(activity_two, user)
assert [_activity_two, _activity_one] =
ActivityPub.fetch_activities([], %{muting_user: user, with_muted: true})
@@ -1340,7 +1358,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
activity = insert(:note_activity)
user = insert(:user)
booster = insert(:user)
- {:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, booster)
+ {:ok, _reblog_mute} = CommonAPI.hide_reblogs(booster, user)
{:ok, activity} = CommonAPI.repeat(activity.id, booster)
@@ -1353,8 +1371,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
activity = insert(:note_activity)
user = insert(:user)
booster = insert(:user)
- {:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, booster)
- {:ok, _reblog_mute} = CommonAPI.show_reblogs(user, booster)
+ {:ok, _reblog_mute} = CommonAPI.hide_reblogs(booster, user)
+ {:ok, _reblog_mute} = CommonAPI.show_reblogs(booster, user)
{:ok, activity} = CommonAPI.repeat(activity.id, booster)
@@ -1434,7 +1452,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
follower = insert(:user)
followed = insert(:user)
- {:ok, _, _, follow_activity} = CommonAPI.follow(follower, followed)
+ {:ok, _, _, follow_activity} = CommonAPI.follow(followed, follower)
with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do
assert {:error, :reverted} = ActivityPub.unfollow(follower, followed)
@@ -1451,7 +1469,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
follower = insert(:user)
followed = insert(:user)
- {:ok, _, _, follow_activity} = CommonAPI.follow(follower, followed)
+ {:ok, _, _, follow_activity} = CommonAPI.follow(followed, follower)
{:ok, activity} = ActivityPub.unfollow(follower, followed)
assert activity.data["type"] == "Undo"
@@ -1468,7 +1486,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
follower = insert(:user)
followed = insert(:user, %{is_locked: true})
- {:ok, _, _, follow_activity} = CommonAPI.follow(follower, followed)
+ {:ok, _, _, follow_activity} = CommonAPI.follow(followed, follower)
{:ok, activity} = ActivityPub.unfollow(follower, followed)
assert activity.data["type"] == "Undo"
@@ -1836,14 +1854,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, a4} = CommonAPI.post(user2, %{status: "Agent Smith "})
{:ok, a5} = CommonAPI.post(user1, %{status: "Red or Blue "})
- {:ok, _} = CommonAPI.favorite(user, a4.id)
- {:ok, _} = CommonAPI.favorite(other_user, a3.id)
- {:ok, _} = CommonAPI.favorite(user, a3.id)
- {:ok, _} = CommonAPI.favorite(other_user, a5.id)
- {:ok, _} = CommonAPI.favorite(user, a5.id)
- {:ok, _} = CommonAPI.favorite(other_user, a4.id)
- {:ok, _} = CommonAPI.favorite(user, a1.id)
- {:ok, _} = CommonAPI.favorite(other_user, a1.id)
+ {:ok, _} = CommonAPI.favorite(a4.id, user)
+ {:ok, _} = CommonAPI.favorite(a3.id, other_user)
+ {:ok, _} = CommonAPI.favorite(a3.id, user)
+ {:ok, _} = CommonAPI.favorite(a5.id, other_user)
+ {:ok, _} = CommonAPI.favorite(a5.id, user)
+ {:ok, _} = CommonAPI.favorite(a4.id, other_user)
+ {:ok, _} = CommonAPI.favorite(a1.id, user)
+ {:ok, _} = CommonAPI.favorite(a1.id, other_user)
result = ActivityPub.fetch_favourites(user)
assert Enum.map(result, & &1.id) == [a1.id, a5.id, a3.id, a4.id]
@@ -2687,7 +2705,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
assert user.name == " "
end
- @tag capture_log: true
test "pin_data_from_featured_collection will ignore unsupported values" do
assert %{} ==
ActivityPub.pin_data_from_featured_collection(%{
diff --git a/test/pleroma/web/activity_pub/mrf/anti_mention_spam_policy_test.exs b/test/pleroma/web/activity_pub/mrf/anti_mention_spam_policy_test.exs
new file mode 100644
index 000000000..63947858c
--- /dev/null
+++ b/test/pleroma/web/activity_pub/mrf/anti_mention_spam_policy_test.exs
@@ -0,0 +1,65 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.MRF.AntiMentionSpamPolicyTest do
+ use Pleroma.DataCase
+ import Pleroma.Factory
+ alias Pleroma.Web.ActivityPub.MRF.AntiMentionSpamPolicy
+
+ test "it allows posts without mentions" do
+ user = insert(:user, local: false)
+ assert user.note_count == 0
+
+ message = %{
+ "type" => "Create",
+ "actor" => user.ap_id
+ }
+
+ {:ok, _message} = AntiMentionSpamPolicy.filter(message)
+ end
+
+ test "it allows posts from users with followers, posts, and age" do
+ user =
+ insert(:user,
+ local: false,
+ follower_count: 1,
+ note_count: 1,
+ inserted_at: ~N[1970-01-01 00:00:00]
+ )
+
+ message = %{
+ "type" => "Create",
+ "actor" => user.ap_id
+ }
+
+ {:ok, _message} = AntiMentionSpamPolicy.filter(message)
+ end
+
+ test "it allows posts from local users" do
+ user = insert(:user, local: true)
+
+ message = %{
+ "type" => "Create",
+ "actor" => user.ap_id
+ }
+
+ {:ok, _message} = AntiMentionSpamPolicy.filter(message)
+ end
+
+ test "it rejects posts with mentions from users without followers" do
+ user = insert(:user, local: false, follower_count: 0)
+
+ message = %{
+ "type" => "Create",
+ "actor" => user.ap_id,
+ "object" => %{
+ "to" => ["https://pleroma.soykaf.com/users/1"],
+ "cc" => ["https://pleroma.soykaf.com/users/1"],
+ "actor" => user.ap_id
+ }
+ }
+
+ {:reject, _message} = AntiMentionSpamPolicy.filter(message)
+ end
+end
diff --git a/test/pleroma/web/activity_pub/mrf/nsfw_api_policy_test.exs b/test/pleroma/web/activity_pub/mrf/nsfw_api_policy_test.exs
new file mode 100644
index 000000000..0beb9c2cb
--- /dev/null
+++ b/test/pleroma/web/activity_pub/mrf/nsfw_api_policy_test.exs
@@ -0,0 +1,267 @@
+# 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.NsfwApiPolicyTest do
+ use Pleroma.DataCase
+
+ import ExUnit.CaptureLog
+ import Pleroma.Factory
+
+ alias Pleroma.Constants
+ alias Pleroma.Web.ActivityPub.MRF.NsfwApiPolicy
+
+ require Pleroma.Constants
+
+ @policy :mrf_nsfw_api
+
+ @sfw_url "https://kittens.co/kitty.gif"
+ @nsfw_url "https://b00bies.com/nsfw.jpg"
+ @timeout_url "http://time.out/i.jpg"
+
+ setup_all do
+ clear_config(@policy,
+ url: "http://127.0.0.1:5000/",
+ threshold: 0.7,
+ mark_sensitive: true,
+ unlist: false,
+ reject: false
+ )
+ end
+
+ setup do
+ Tesla.Mock.mock(fn
+ # NSFW URL
+ %{method: :get, url: "http://127.0.0.1:5000/?url=#{@nsfw_url}"} ->
+ %Tesla.Env{status: 200, body: ~s({"score":0.99772077798843384,"url":"#{@nsfw_url}"})}
+
+ # SFW URL
+ %{method: :get, url: "http://127.0.0.1:5000/?url=#{@sfw_url}"} ->
+ %Tesla.Env{status: 200, body: ~s({"score":0.00011714912398019806,"url":"#{@sfw_url}"})}
+
+ # Timeout URL
+ %{method: :get, url: "http://127.0.0.1:5000/?url=#{@timeout_url}"} ->
+ {:error, :timeout}
+
+ # Fallback URL
+ %{method: :get, url: "http://127.0.0.1:5000/?url=" <> url} ->
+ body =
+ ~s({"error_code":500,"error_reason":"[Errno -2] Name or service not known","url":"#{url}"})
+
+ %Tesla.Env{status: 500, body: body}
+ end)
+
+ :ok
+ end
+
+ describe "build_request_url/1" do
+ test "it works" do
+ expected = "http://127.0.0.1:5000/?url=https://b00bies.com/nsfw.jpg"
+ assert NsfwApiPolicy.build_request_url(@nsfw_url) == expected
+ end
+
+ test "it adds a trailing slash" do
+ clear_config([@policy, :url], "http://localhost:5000")
+
+ expected = "http://localhost:5000/?url=https://b00bies.com/nsfw.jpg"
+ assert NsfwApiPolicy.build_request_url(@nsfw_url) == expected
+ end
+
+ test "it adds a trailing slash preserving the path" do
+ clear_config([@policy, :url], "http://localhost:5000/nsfw_api")
+
+ expected = "http://localhost:5000/nsfw_api/?url=https://b00bies.com/nsfw.jpg"
+ assert NsfwApiPolicy.build_request_url(@nsfw_url) == expected
+ end
+ end
+
+ describe "parse_url/1" do
+ test "returns decoded JSON from the API server" do
+ expected = %{"score" => 0.99772077798843384, "url" => @nsfw_url}
+ assert NsfwApiPolicy.parse_url(@nsfw_url) == {:ok, expected}
+ end
+
+ test "warns when the API server fails" do
+ expected = "[NsfwApiPolicy]: The API server failed. Skipping."
+ assert capture_log(fn -> NsfwApiPolicy.parse_url(@timeout_url) end) =~ expected
+ end
+
+ test "returns {:error, _} tuple when the API server fails" do
+ capture_log(fn ->
+ assert {:error, _} = NsfwApiPolicy.parse_url(@timeout_url)
+ end)
+ end
+ end
+
+ describe "check_url_nsfw/1" do
+ test "returns {:nsfw, _} tuple" do
+ expected = {:nsfw, %{url: @nsfw_url, score: 0.99772077798843384, threshold: 0.7}}
+ assert NsfwApiPolicy.check_url_nsfw(@nsfw_url) == expected
+ end
+
+ test "returns {:sfw, _} tuple" do
+ expected = {:sfw, %{url: @sfw_url, score: 0.00011714912398019806, threshold: 0.7}}
+ assert NsfwApiPolicy.check_url_nsfw(@sfw_url) == expected
+ end
+
+ test "returns {:sfw, _} on failure" do
+ expected = {:sfw, %{url: @timeout_url, score: nil, threshold: 0.7}}
+
+ capture_log(fn ->
+ assert NsfwApiPolicy.check_url_nsfw(@timeout_url) == expected
+ end)
+ end
+
+ test "works with map URL" do
+ expected = {:nsfw, %{url: @nsfw_url, score: 0.99772077798843384, threshold: 0.7}}
+ assert NsfwApiPolicy.check_url_nsfw(%{"href" => @nsfw_url}) == expected
+ end
+ end
+
+ describe "check_attachment_nsfw/1" do
+ test "returns {:nsfw, _} if any items are NSFW" do
+ attachment = %{"url" => [%{"href" => @nsfw_url}, @nsfw_url, @sfw_url]}
+ assert NsfwApiPolicy.check_attachment_nsfw(attachment) == {:nsfw, attachment}
+ end
+
+ test "returns {:sfw, _} if all items are SFW" do
+ attachment = %{"url" => [%{"href" => @sfw_url}, @sfw_url, @sfw_url]}
+ assert NsfwApiPolicy.check_attachment_nsfw(attachment) == {:sfw, attachment}
+ end
+
+ test "works with binary URL" do
+ attachment = %{"url" => @nsfw_url}
+ assert NsfwApiPolicy.check_attachment_nsfw(attachment) == {:nsfw, attachment}
+ end
+ end
+
+ describe "check_object_nsfw/1" do
+ test "returns {:nsfw, _} if any items are NSFW" do
+ object = %{"attachment" => [%{"url" => [%{"href" => @nsfw_url}, @sfw_url]}]}
+ assert NsfwApiPolicy.check_object_nsfw(object) == {:nsfw, object}
+ end
+
+ test "returns {:sfw, _} if all items are SFW" do
+ object = %{"attachment" => [%{"url" => [%{"href" => @sfw_url}, @sfw_url]}]}
+ assert NsfwApiPolicy.check_object_nsfw(object) == {:sfw, object}
+ end
+
+ test "works with embedded object" do
+ object = %{"object" => %{"attachment" => [%{"url" => [%{"href" => @nsfw_url}, @sfw_url]}]}}
+ assert NsfwApiPolicy.check_object_nsfw(object) == {:nsfw, object}
+ end
+ end
+
+ describe "unlist/1" do
+ test "unlist addressing" do
+ user = insert(:user)
+
+ object = %{
+ "to" => [Constants.as_public()],
+ "cc" => [user.follower_address, "https://hello.world/users/alex"],
+ "actor" => user.ap_id
+ }
+
+ expected = %{
+ "to" => [user.follower_address],
+ "cc" => [Constants.as_public(), "https://hello.world/users/alex"],
+ "actor" => user.ap_id
+ }
+
+ assert NsfwApiPolicy.unlist(object) == expected
+ end
+
+ test "raise if user isn't found" do
+ object = %{
+ "to" => [Constants.as_public()],
+ "cc" => [],
+ "actor" => "https://hello.world/users/alex"
+ }
+
+ assert_raise(RuntimeError, fn ->
+ NsfwApiPolicy.unlist(object)
+ end)
+ end
+ end
+
+ describe "mark_sensitive/1" do
+ test "adds nsfw tag and marks sensitive" do
+ object = %{"tag" => ["yolo"]}
+ expected = %{"tag" => ["yolo", "nsfw"], "sensitive" => true}
+ assert NsfwApiPolicy.mark_sensitive(object) == expected
+ end
+
+ test "works with embedded object" do
+ object = %{"object" => %{"tag" => ["yolo"]}}
+ expected = %{"object" => %{"tag" => ["yolo", "nsfw"], "sensitive" => true}}
+ assert NsfwApiPolicy.mark_sensitive(object) == expected
+ end
+ end
+
+ describe "filter/1" do
+ setup do
+ user = insert(:user)
+
+ nsfw_object = %{
+ "to" => [Constants.as_public()],
+ "cc" => [user.follower_address],
+ "actor" => user.ap_id,
+ "attachment" => [%{"url" => @nsfw_url}]
+ }
+
+ sfw_object = %{
+ "to" => [Constants.as_public()],
+ "cc" => [user.follower_address],
+ "actor" => user.ap_id,
+ "attachment" => [%{"url" => @sfw_url}]
+ }
+
+ %{user: user, nsfw_object: nsfw_object, sfw_object: sfw_object}
+ end
+
+ test "passes SFW object through", %{sfw_object: object} do
+ {:ok, _} = NsfwApiPolicy.filter(object)
+ end
+
+ test "passes NSFW object through when actions are disabled", %{nsfw_object: object} do
+ clear_config([@policy, :mark_sensitive], false)
+ clear_config([@policy, :unlist], false)
+ clear_config([@policy, :reject], false)
+ {:ok, _} = NsfwApiPolicy.filter(object)
+ end
+
+ test "passes NSFW object through when :threshold is 1", %{nsfw_object: object} do
+ clear_config([@policy, :reject], true)
+ clear_config([@policy, :threshold], 1)
+ {:ok, _} = NsfwApiPolicy.filter(object)
+ end
+
+ test "rejects SFW object through when :threshold is 0", %{sfw_object: object} do
+ clear_config([@policy, :reject], true)
+ clear_config([@policy, :threshold], 0)
+ {:reject, _} = NsfwApiPolicy.filter(object)
+ end
+
+ test "rejects NSFW when :reject is enabled", %{nsfw_object: object} do
+ clear_config([@policy, :reject], true)
+ {:reject, _} = NsfwApiPolicy.filter(object)
+ end
+
+ test "passes NSFW through when :reject is disabled", %{nsfw_object: object} do
+ clear_config([@policy, :reject], false)
+ {:ok, _} = NsfwApiPolicy.filter(object)
+ end
+
+ test "unlists NSFW when :unlist is enabled", %{user: user, nsfw_object: object} do
+ clear_config([@policy, :unlist], true)
+ {:ok, object} = NsfwApiPolicy.filter(object)
+ assert object["to"] == [user.follower_address]
+ end
+
+ test "passes NSFW through when :unlist is disabled", %{nsfw_object: object} do
+ clear_config([@policy, :unlist], false)
+ {:ok, object} = NsfwApiPolicy.filter(object)
+ assert object["to"] == [Constants.as_public()]
+ end
+ end
+end
diff --git a/test/pleroma/web/activity_pub/mrf/simple_policy_test.exs b/test/pleroma/web/activity_pub/mrf/simple_policy_test.exs
index 57fc00af5..1a51b7d30 100644
--- a/test/pleroma/web/activity_pub/mrf/simple_policy_test.exs
+++ b/test/pleroma/web/activity_pub/mrf/simple_policy_test.exs
@@ -318,7 +318,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
following_user = insert(:user)
non_following_user = insert(:user)
- {:ok, _, _, _} = CommonAPI.follow(following_user, actor)
+ {:ok, _, _, _} = CommonAPI.follow(actor, following_user)
activity = %{
"actor" => actor.ap_id,
diff --git a/test/pleroma/web/activity_pub/mrf_test.exs b/test/pleroma/web/activity_pub/mrf_test.exs
index 3ead73792..25548e3da 100644
--- a/test/pleroma/web/activity_pub/mrf_test.exs
+++ b/test/pleroma/web/activity_pub/mrf_test.exs
@@ -65,7 +65,6 @@ defmodule Pleroma.Web.ActivityPub.MRFTest do
refute MRF.subdomain_match?(regexes, "example.com")
end
- @tag capture_log: true
test "logs sensible error on accidental wildcard" do
assert_raise Regex.CompileError, fn ->
assert capture_log(MRF.subdomains_regex(["*unsafe.tld"])) =~
diff --git a/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs b/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs
index 511637e1d..b711d8e91 100644
--- a/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs
+++ b/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs
@@ -43,7 +43,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidatorTest
setup do
user = insert(:user)
{:ok, activity} = Pleroma.Web.CommonAPI.post(user, %{status: "mew mew :dinosaur:"})
- {:ok, edit} = Pleroma.Web.CommonAPI.update(user, activity, %{status: "edited :blank:"})
+ {:ok, edit} = Pleroma.Web.CommonAPI.update(activity, user, %{status: "edited :blank:"})
{:ok, %{"object" => external_rep}} =
Pleroma.Web.ActivityPub.Transmogrifier.prepare_outgoing(edit.data)
diff --git a/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs b/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs
index a615c1d9a..6627fa6db 100644
--- a/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs
+++ b/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs
@@ -27,19 +27,22 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidatorTest do
end
test "works with honkerific attachments" do
- attachment = %{
+ honk = %{
"mediaType" => "",
- "name" => "",
- "summary" => "298p3RG7j27tfsZ9RQ.jpg",
+ "summary" => "Select your spirit chonk",
+ "name" => "298p3RG7j27tfsZ9RQ.jpg",
"type" => "Document",
"url" => "https://honk.tedunangst.com/d/298p3RG7j27tfsZ9RQ.jpg"
}
assert {:ok, attachment} =
- AttachmentValidator.cast_and_validate(attachment)
+ honk
+ |> AttachmentValidator.cast_and_validate()
|> Ecto.Changeset.apply_action(:insert)
assert attachment.mediaType == "application/octet-stream"
+ assert attachment.summary == "Select your spirit chonk"
+ assert attachment.name == "298p3RG7j27tfsZ9RQ.jpg"
end
test "works with an unknown but valid mime type" do
diff --git a/test/pleroma/web/activity_pub/object_validators/like_validation_test.exs b/test/pleroma/web/activity_pub/object_validators/like_validation_test.exs
index ebc181a6d..620173119 100644
--- a/test/pleroma/web/activity_pub/object_validators/like_validation_test.exs
+++ b/test/pleroma/web/activity_pub/object_validators/like_validation_test.exs
@@ -94,7 +94,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.LikeValidationTest do
user: user,
post_activity: post_activity
} do
- _like = CommonAPI.favorite(user, post_activity.id)
+ _like = CommonAPI.favorite(post_activity.id, user)
refute LikeValidator.cast_and_validate(valid_like).valid?
end
diff --git a/test/pleroma/web/activity_pub/object_validators/undo_handling_test.exs b/test/pleroma/web/activity_pub/object_validators/undo_handling_test.exs
index db95b8e3c..589b70ac7 100644
--- a/test/pleroma/web/activity_pub/object_validators/undo_handling_test.exs
+++ b/test/pleroma/web/activity_pub/object_validators/undo_handling_test.exs
@@ -15,7 +15,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.UndoHandlingTest do
setup do
user = insert(:user)
{:ok, post_activity} = CommonAPI.post(user, %{status: "uguu"})
- {:ok, like} = CommonAPI.favorite(user, post_activity.id)
+ {:ok, like} = CommonAPI.favorite(post_activity.id, user)
{:ok, valid_like_undo, []} = Builder.undo(user, like)
%{user: user, like: like, valid_like_undo: valid_like_undo}
diff --git a/test/pleroma/web/activity_pub/object_validators/update_handling_test.exs b/test/pleroma/web/activity_pub/object_validators/update_handling_test.exs
index a09dbf5c6..c88339d14 100644
--- a/test/pleroma/web/activity_pub/object_validators/update_handling_test.exs
+++ b/test/pleroma/web/activity_pub/object_validators/update_handling_test.exs
@@ -132,7 +132,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.UpdateHandlingTest do
setup do
user = insert(:user)
{:ok, activity} = Pleroma.Web.CommonAPI.post(user, %{status: "mew mew :dinosaur:"})
- {:ok, edit} = Pleroma.Web.CommonAPI.update(user, activity, %{status: "edited :blank:"})
+ {:ok, edit} = Pleroma.Web.CommonAPI.update(activity, user, %{status: "edited :blank:"})
{:ok, external_rep} = Pleroma.Web.ActivityPub.Transmogrifier.prepare_outgoing(edit.data)
%{external_rep: external_rep}
end
diff --git a/test/pleroma/web/activity_pub/publisher_test.exs b/test/pleroma/web/activity_pub/publisher_test.exs
index 870f1f77a..6f48a0227 100644
--- a/test/pleroma/web/activity_pub/publisher_test.exs
+++ b/test/pleroma/web/activity_pub/publisher_test.exs
@@ -216,7 +216,6 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
refute called(Instances.set_reachable(inbox))
end
- @tag capture_log: true
test_with_mock "calls `Instances.set_unreachable` on target inbox on non-2xx HTTP response code",
Instances,
[:passthrough],
@@ -224,7 +223,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
actor = insert(:user)
inbox = "http://404.site/users/nick1/inbox"
- assert {:discard, _} =
+ assert {:cancel, _} =
Publisher.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1})
assert called(Instances.set_unreachable(inbox))
diff --git a/test/pleroma/web/activity_pub/relay_test.exs b/test/pleroma/web/activity_pub/relay_test.exs
index ec9b0f09a..7c45593ed 100644
--- a/test/pleroma/web/activity_pub/relay_test.exs
+++ b/test/pleroma/web/activity_pub/relay_test.exs
@@ -53,7 +53,7 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
test "returns activity" do
user = insert(:user)
service_actor = Relay.get_actor()
- CommonAPI.follow(service_actor, user)
+ CommonAPI.follow(user, service_actor)
assert "#{user.ap_id}/followers" in User.following(service_actor)
assert {:ok, %Activity{} = activity} = Relay.unfollow(user.ap_id)
assert activity.actor == "#{Pleroma.Web.Endpoint.url()}/relay"
@@ -74,7 +74,7 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
end)
service_actor = Relay.get_actor()
- CommonAPI.follow(service_actor, user)
+ CommonAPI.follow(user, service_actor)
assert "#{user.ap_id}/followers" in User.following(service_actor)
assert Pleroma.Repo.get_by(
@@ -113,7 +113,6 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
assert Relay.publish(activity) == {:error, "Not implemented"}
end
- @tag capture_log: true
test "returns error when activity not public" do
activity = insert(:direct_note_activity)
assert Relay.publish(activity) == {:error, false}
diff --git a/test/pleroma/web/activity_pub/side_effects/delete_test.exs b/test/pleroma/web/activity_pub/side_effects/delete_test.exs
index 9a2703c4c..637007b7e 100644
--- a/test/pleroma/web/activity_pub/side_effects/delete_test.exs
+++ b/test/pleroma/web/activity_pub/side_effects/delete_test.exs
@@ -50,7 +50,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects.DeleteTest do
{:ok, op} = CommonAPI.post(other_user, %{status: "big oof"})
{:ok, post} = CommonAPI.post(user, %{status: "hey", in_reply_to_id: op})
- {:ok, favorite} = CommonAPI.favorite(user, post.id)
+ {:ok, favorite} = CommonAPI.favorite(post.id, user)
object = Object.normalize(post, fetch: false)
{:ok, delete_data, _meta} = Builder.delete(user, object.data["id"])
{:ok, delete, _meta} = ActivityPub.persist(delete_data, local: true)
diff --git a/test/pleroma/web/activity_pub/side_effects_test.exs b/test/pleroma/web/activity_pub/side_effects_test.exs
index 7af50e12c..68922e536 100644
--- a/test/pleroma/web/activity_pub/side_effects_test.exs
+++ b/test/pleroma/web/activity_pub/side_effects_test.exs
@@ -516,10 +516,10 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
poster = insert(:user)
user = insert(:user)
{:ok, post} = CommonAPI.post(poster, %{status: "hey"})
- {:ok, like} = CommonAPI.favorite(user, post.id)
+ {:ok, like} = CommonAPI.favorite(post.id, user)
{:ok, reaction} = CommonAPI.react_with_emoji(post.id, user, "👍")
{:ok, announce} = CommonAPI.repeat(post.id, user)
- {:ok, block} = CommonAPI.block(user, poster)
+ {:ok, block} = CommonAPI.block(poster, user)
{:ok, undo_data, _meta} = Builder.undo(user, like)
{:ok, like_undo, _meta} = ActivityPub.persist(undo_data, local: true)
@@ -834,7 +834,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
user = insert(:user)
followed = insert(:user)
- {:ok, _, _, follow_activity} = CommonAPI.follow(user, followed)
+ {:ok, _, _, follow_activity} = CommonAPI.follow(followed, user)
{:ok, reject_data, []} = Builder.reject(followed, follow_activity)
{:ok, reject, _meta} = ActivityPub.persist(reject_data, local: true)
@@ -965,7 +965,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
group: group,
poster: poster
} do
- {:ok, _} = CommonAPI.block(group, poster)
+ {:ok, _} = CommonAPI.block(poster, group)
create_activity_data = make_create.([group])
{:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
diff --git a/test/pleroma/web/activity_pub/transmogrifier/accept_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/accept_handling_test.exs
index 968fd4ede..4209a24a7 100644
--- a/test/pleroma/web/activity_pub/transmogrifier/accept_handling_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier/accept_handling_test.exs
@@ -18,7 +18,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AcceptHandlingTest do
{:ok, follower, followed} = User.follow(follower, followed)
assert User.following?(follower, followed) == true
- {:ok, _, _, follow_activity} = CommonAPI.follow(follower, followed)
+ {:ok, _, _, follow_activity} = CommonAPI.follow(followed, follower)
accept_data =
File.read!("test/fixtures/mastodon-accept-activity.json")
@@ -48,7 +48,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AcceptHandlingTest do
follower = insert(:user)
followed = insert(:user, is_locked: true)
- {:ok, _, _, follow_activity} = CommonAPI.follow(follower, followed)
+ {:ok, _, _, follow_activity} = CommonAPI.follow(followed, follower)
accept_data =
File.read!("test/fixtures/mastodon-accept-activity.json")
diff --git a/test/pleroma/web/activity_pub/transmogrifier/announce_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/announce_handling_test.exs
index 9521cc0ab..f55f42c10 100644
--- a/test/pleroma/web/activity_pub/transmogrifier/announce_handling_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier/announce_handling_test.exs
@@ -83,7 +83,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AnnounceHandlingTest do
assert(Activity.get_create_by_object_ap_id(data["object"]))
end
- @tag capture_log: true
test "it works for incoming announces with an existing activity" do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "hey"})
@@ -136,7 +135,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AnnounceHandlingTest do
assert object.data["content"] == "this is a private toot"
end
- @tag capture_log: true
test "it rejects incoming announces with an inlined activity from another origin" do
Tesla.Mock.mock(fn
%{method: :get} -> %Tesla.Env{status: 404, body: ""}
diff --git a/test/pleroma/web/activity_pub/transmogrifier/delete_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/delete_handling_test.exs
index 4a7ff5158..300151fb2 100644
--- a/test/pleroma/web/activity_pub/transmogrifier/delete_handling_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier/delete_handling_test.exs
@@ -86,7 +86,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.DeleteHandlingTest do
assert match?({:error, _}, Transmogrifier.handle_incoming(data))
end
- @tag capture_log: true
test "it works for incoming user deletes" do
%{ap_id: ap_id} = insert(:user, ap_id: "http://mastodon.example.org/users/admin")
diff --git a/test/pleroma/web/activity_pub/transmogrifier/emoji_tag_building_test.exs b/test/pleroma/web/activity_pub/transmogrifier/emoji_tag_building_test.exs
new file mode 100644
index 000000000..c632c199c
--- /dev/null
+++ b/test/pleroma/web/activity_pub/transmogrifier/emoji_tag_building_test.exs
@@ -0,0 +1,14 @@
+defmodule Pleroma.Web.ActivityPub.Transmogrifier.EmojiTagBuildingTest do
+ use Pleroma.DataCase, async: true
+
+ alias Pleroma.Web.ActivityPub.Transmogrifier
+
+ test "it encodes the id to be a valid url" do
+ name = "hanapog"
+ url = "https://misskey.local.live/emojis/hana pog.png"
+
+ tag = Transmogrifier.build_emoji_tag({name, url})
+
+ assert tag["id"] == "https://misskey.local.live/emojis/hana%20pog.png"
+ end
+end
diff --git a/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs
index dc1483288..fd7a3c772 100644
--- a/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs
@@ -56,7 +56,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
assert activity == returned_activity
end
- @tag capture_log: true
test "it fetches reply-to activities if we don't have them" do
data =
File.read!("test/fixtures/mastodon-post-activity.json")
@@ -104,7 +103,6 @@ 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")
@@ -581,7 +579,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
assert modified_object["inReplyTo"] == []
end
- @tag capture_log: true
test "returns modified object when allowed incoming reply", %{data: data} do
object_with_reply =
Map.put(
@@ -767,7 +764,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
assert modified.data["context"] == object.data["id"]
end
- @tag capture_log: true
test "the reply note uses its parent's ID when context is missing and reply is unreachable" do
insert(:user, ap_id: "https://mk.absturztau.be/users/8ozbzjs3o8")
diff --git a/test/pleroma/web/activity_pub/transmogrifier/reject_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/reject_handling_test.exs
index 11562422d..225898e85 100644
--- a/test/pleroma/web/activity_pub/transmogrifier/reject_handling_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier/reject_handling_test.exs
@@ -36,7 +36,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.RejectHandlingTest do
followed = insert(:user, is_locked: true)
{:ok, follower, followed} = User.follow(follower, followed)
- {:ok, _, _, follow_activity} = CommonAPI.follow(follower, followed)
+ {:ok, _, _, follow_activity} = CommonAPI.follow(followed, follower)
assert User.following?(follower, followed) == true
diff --git a/test/pleroma/web/activity_pub/transmogrifier_test.exs b/test/pleroma/web/activity_pub/transmogrifier_test.exs
index 8fbcf15f1..ebf70b3e6 100644
--- a/test/pleroma/web/activity_pub/transmogrifier_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier_test.exs
@@ -353,7 +353,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "everybody do the dinosaur :dinosaur:"})
- {:ok, update} = CommonAPI.update(user, activity, %{status: "mew mew :blank:"})
+ {:ok, update} = CommonAPI.update(activity, user, %{status: "mew mew :blank:"})
{:ok, prepared} = Transmogrifier.prepare_outgoing(update.data)
@@ -554,7 +554,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
end) =~ "Unsupported URI scheme"
end
- @tag capture_log: true
test "returns {:ok, %Object{}} for success case" do
assert {:ok, %Object{}} =
Transmogrifier.get_obj_helper(
diff --git a/test/pleroma/web/activity_pub/utils_test.exs b/test/pleroma/web/activity_pub/utils_test.exs
index b7c4417a8..45fef154e 100644
--- a/test/pleroma/web/activity_pub/utils_test.exs
+++ b/test/pleroma/web/activity_pub/utils_test.exs
@@ -215,7 +215,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
})
object = Object.normalize(activity, fetch: false)
- {:ok, votes, object} = CommonAPI.vote(other_user, object, [0, 1])
+ {:ok, votes, object} = CommonAPI.vote(object, other_user, [0, 1])
assert Enum.sort(Utils.get_existing_votes(other_user.ap_id, object)) == Enum.sort(votes)
end
@@ -233,8 +233,8 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
})
object = Object.normalize(activity, fetch: false)
- {:ok, [vote], object} = CommonAPI.vote(other_user, object, [0])
- {:ok, _activity} = CommonAPI.favorite(user, activity.id)
+ {:ok, [vote], object} = CommonAPI.vote(object, other_user, [0])
+ {:ok, _activity} = CommonAPI.favorite(activity.id, user)
[fetched_vote] = Utils.get_existing_votes(other_user.ap_id, object)
assert fetched_vote.id == vote.id
end
@@ -245,8 +245,8 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
user = insert(:user, is_locked: true)
follower = insert(:user)
- {:ok, _, _, follow_activity} = CommonAPI.follow(follower, user)
- {:ok, _, _, follow_activity_two} = CommonAPI.follow(follower, user)
+ {:ok, _, _, follow_activity} = CommonAPI.follow(user, follower)
+ {:ok, _, _, follow_activity_two} = CommonAPI.follow(user, follower)
data =
follow_activity_two.data
@@ -267,8 +267,8 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
user = insert(:user)
follower = insert(:user)
- {:ok, _, _, follow_activity} = CommonAPI.follow(follower, user)
- {:ok, _, _, follow_activity_two} = CommonAPI.follow(follower, user)
+ {:ok, _, _, follow_activity} = CommonAPI.follow(user, follower)
+ {:ok, _, _, follow_activity_two} = CommonAPI.follow(user, follower)
{:ok, follow_activity_two} =
Utils.update_follow_state_for_all(follow_activity_two, "reject")
@@ -283,8 +283,8 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
user = insert(:user, is_locked: true)
follower = insert(:user)
- {:ok, _, _, follow_activity} = CommonAPI.follow(follower, user)
- {:ok, _, _, follow_activity_two} = CommonAPI.follow(follower, user)
+ {:ok, _, _, follow_activity} = CommonAPI.follow(user, follower)
+ {:ok, _, _, follow_activity_two} = CommonAPI.follow(user, follower)
data =
follow_activity_two.data
@@ -369,7 +369,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
user = insert(:user)
refute Utils.get_existing_like(user.ap_id, object)
- {:ok, like_activity} = CommonAPI.favorite(user, note_activity.id)
+ {:ok, like_activity} = CommonAPI.favorite(note_activity.id, user)
assert ^like_activity = Utils.get_existing_like(user.ap_id, object)
end
@@ -396,9 +396,9 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
user1 = insert(:user)
user2 = insert(:user)
- assert {:ok, %Activity{} = _} = CommonAPI.block(user1, user2)
- assert {:ok, %Activity{} = _} = CommonAPI.block(user1, user2)
- assert {:ok, %Activity{} = activity} = CommonAPI.block(user1, user2)
+ assert {:ok, %Activity{} = _} = CommonAPI.block(user2, user1)
+ assert {:ok, %Activity{} = _} = CommonAPI.block(user2, user1)
+ assert {:ok, %Activity{} = activity} = CommonAPI.block(user2, user1)
assert Utils.fetch_latest_block(user1, user2) == activity
end
@@ -560,7 +560,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
target_account = insert(:user)
{:ok, activity} = CommonAPI.post(posting_account, %{status: "foobar"})
- {:ok, like} = CommonAPI.favorite(target_account, activity.id)
+ {:ok, like} = CommonAPI.favorite(activity.id, target_account)
context = Utils.generate_context_id()
content = "foobar"
diff --git a/test/pleroma/web/activity_pub/views/object_view_test.exs b/test/pleroma/web/activity_pub/views/object_view_test.exs
index d94878e31..14258795f 100644
--- a/test/pleroma/web/activity_pub/views/object_view_test.exs
+++ b/test/pleroma/web/activity_pub/views/object_view_test.exs
@@ -59,7 +59,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectViewTest do
object = Object.normalize(note, fetch: false)
user = insert(:user)
- {:ok, like_activity} = CommonAPI.favorite(user, note.id)
+ {:ok, like_activity} = CommonAPI.favorite(note.id, user)
result = ObjectView.render("object.json", %{object: like_activity})
diff --git a/test/pleroma/web/activity_pub/views/user_view_test.exs b/test/pleroma/web/activity_pub/views/user_view_test.exs
index c75149dab..c94f8a2bc 100644
--- a/test/pleroma/web/activity_pub/views/user_view_test.exs
+++ b/test/pleroma/web/activity_pub/views/user_view_test.exs
@@ -138,7 +138,7 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
test "sets totalItems to zero when followers are hidden" do
user = insert(:user)
other_user = insert(:user)
- {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
+ {:ok, _other_user, user, _activity} = CommonAPI.follow(user, other_user)
assert %{"totalItems" => 1} = UserView.render("followers.json", %{user: user})
user = Map.merge(user, %{hide_followers_count: true, hide_followers: true})
refute UserView.render("followers.json", %{user: user}) |> Map.has_key?("totalItems")
@@ -147,7 +147,7 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
test "sets correct totalItems when followers are hidden but the follower counter is not" do
user = insert(:user)
other_user = insert(:user)
- {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
+ {:ok, _other_user, user, _activity} = CommonAPI.follow(user, other_user)
assert %{"totalItems" => 1} = UserView.render("followers.json", %{user: user})
user = Map.merge(user, %{hide_followers_count: false, hide_followers: true})
assert %{"totalItems" => 1} = UserView.render("followers.json", %{user: user})
@@ -158,7 +158,7 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
test "sets totalItems to zero when follows are hidden" do
user = insert(:user)
other_user = insert(:user)
- {:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)
+ {:ok, user, _other_user, _activity} = CommonAPI.follow(other_user, user)
assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user})
user = Map.merge(user, %{hide_follows_count: true, hide_follows: true})
assert %{"totalItems" => 0} = UserView.render("following.json", %{user: user})
@@ -167,7 +167,7 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
test "sets correct totalItems when follows are hidden but the follow counter is not" do
user = insert(:user)
other_user = insert(:user)
- {:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)
+ {:ok, user, _other_user, _activity} = CommonAPI.follow(other_user, user)
assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user})
user = Map.merge(user, %{hide_follows_count: false, hide_follows: true})
assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user})
diff --git a/test/pleroma/web/admin_api/controllers/config_controller_test.exs b/test/pleroma/web/admin_api/controllers/config_controller_test.exs
index 734aca752..dc12155f5 100644
--- a/test/pleroma/web/admin_api/controllers/config_controller_test.exs
+++ b/test/pleroma/web/admin_api/controllers/config_controller_test.exs
@@ -194,7 +194,6 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
setup do: clear_config(:configurable_from_database, true)
- @tag capture_log: true
test "create new config setting in db", %{conn: conn} do
ueberauth = Application.get_env(:ueberauth, Ueberauth)
on_exit(fn -> Application.put_env(:ueberauth, Ueberauth, ueberauth) end)
@@ -316,7 +315,6 @@ 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)
@@ -611,52 +609,6 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
]
end
- test "saving full setting if value is in full_key_update list", %{conn: conn} do
- backends = Application.get_env(:logger, :backends)
- on_exit(fn -> Application.put_env(:logger, :backends, backends) end)
-
- insert(:config,
- group: :logger,
- key: :backends,
- value: []
- )
-
- Pleroma.Config.TransferTask.load_and_update_env([], false)
-
- assert Application.get_env(:logger, :backends) == []
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{
- group: ":logger",
- key: ":backends",
- value: [":console"]
- }
- ]
- })
-
- assert json_response_and_validate_schema(conn, 200) == %{
- "configs" => [
- %{
- "group" => ":logger",
- "key" => ":backends",
- "value" => [
- ":console"
- ],
- "db" => [":backends"]
- }
- ],
- "need_reboot" => false
- }
-
- assert Application.get_env(:logger, :backends) == [
- :console
- ]
- end
-
test "saving full setting if value is not keyword", %{conn: conn} do
insert(:config,
group: :tesla,
@@ -1229,7 +1181,6 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
assert ":proxy_url" in db
end
- @tag capture_log: true
test "doesn't set keys not in the whitelist", %{conn: conn} do
clear_config(:database_config_whitelist, [
{:pleroma, :key1},
diff --git a/test/pleroma/web/admin_api/controllers/user_controller_test.exs b/test/pleroma/web/admin_api/controllers/user_controller_test.exs
index 8edfda54c..c8495c477 100644
--- a/test/pleroma/web/admin_api/controllers/user_controller_test.exs
+++ b/test/pleroma/web/admin_api/controllers/user_controller_test.exs
@@ -69,8 +69,8 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do
# Create some activities to check they got deleted later
follower = insert(:user)
{:ok, _} = CommonAPI.post(user, %{status: "test"})
- {:ok, _, _, _} = CommonAPI.follow(user, follower)
{:ok, _, _, _} = CommonAPI.follow(follower, user)
+ {:ok, _, _, _} = CommonAPI.follow(user, follower)
user = Repo.get(User, user.id)
assert user.note_count == 1
assert user.follower_count == 1
diff --git a/test/pleroma/web/common_api_test.exs b/test/pleroma/web/common_api_test.exs
index 58cd1fd42..b6fba6999 100644
--- a/test/pleroma/web/common_api_test.exs
+++ b/test/pleroma/web/common_api_test.exs
@@ -13,6 +13,7 @@ defmodule Pleroma.Web.CommonAPITest do
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.Rule
+ alias Pleroma.Tests.ObanHelpers
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
@@ -22,7 +23,7 @@ defmodule Pleroma.Web.CommonAPITest do
alias Pleroma.Web.CommonAPI
alias Pleroma.Workers.PollWorker
- import Ecto.Query, only: [from: 2]
+ import Ecto.Query, only: [from: 2, where: 3]
import Mock
import Mox
import Pleroma.Factory
@@ -79,8 +80,8 @@ defmodule Pleroma.Web.CommonAPITest do
setup do
blocker = insert(:user)
blocked = insert(:user, local: false)
- CommonAPI.follow(blocker, blocked)
CommonAPI.follow(blocked, blocker)
+ CommonAPI.follow(blocker, blocked)
CommonAPI.accept_follow_request(blocker, blocked)
CommonAPI.accept_follow_request(blocked, blocked)
%{blocker: blocker, blocked: blocked}
@@ -94,7 +95,7 @@ defmodule Pleroma.Web.CommonAPITest do
assert User.get_follow_state(blocker, blocked) == :follow_accept
refute is_nil(Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(blocker, blocked))
- assert {:ok, block} = CommonAPI.block(blocker, blocked)
+ assert {:ok, block} = CommonAPI.block(blocked, blocker)
assert block.local
assert User.blocks?(blocker, blocked)
@@ -119,7 +120,7 @@ defmodule Pleroma.Web.CommonAPITest do
with_mock Pleroma.Web.Federator,
publish: fn _ -> nil end do
- assert {:ok, block} = CommonAPI.block(blocker, blocked)
+ assert {:ok, block} = CommonAPI.block(blocked, blocker)
assert block.local
assert User.blocks?(blocker, blocked)
@@ -323,7 +324,7 @@ defmodule Pleroma.Web.CommonAPITest do
User.block(blocker, blocked)
assert User.blocks?(blocker, blocked)
- assert {:ok, :no_activity} == CommonAPI.unblock(blocker, blocked)
+ assert {:ok, :no_activity} == CommonAPI.unblock(blocked, blocker)
refute User.blocks?(blocker, blocked)
end
end
@@ -453,7 +454,7 @@ defmodule Pleroma.Web.CommonAPITest do
users_serial
|> Enum.map(fn user ->
- CommonAPI.favorite(user, activity.id)
+ CommonAPI.favorite(activity.id, user)
end)
object = Object.get_by_ap_id(activity.data["object"])
@@ -462,7 +463,7 @@ defmodule Pleroma.Web.CommonAPITest do
users
|> Enum.map(fn user ->
Task.async(fn ->
- CommonAPI.favorite(user, activity.id)
+ CommonAPI.favorite(activity.id, user)
end)
end)
|> Enum.map(&Task.await/1)
@@ -954,7 +955,7 @@ defmodule Pleroma.Web.CommonAPITest do
test "author can repeat own private statuses" do
author = insert(:user)
follower = insert(:user)
- CommonAPI.follow(follower, author)
+ CommonAPI.follow(author, follower)
{:ok, activity} = CommonAPI.post(author, %{status: "cofe", visibility: "private"})
@@ -973,7 +974,7 @@ defmodule Pleroma.Web.CommonAPITest do
{:ok, post_activity} = CommonAPI.post(other_user, %{status: "cofe"})
- {:ok, %Activity{data: data}} = CommonAPI.favorite(user, post_activity.id)
+ {:ok, %Activity{data: data}} = CommonAPI.favorite(post_activity.id, user)
assert data["type"] == "Like"
assert data["actor"] == user.ap_id
assert data["object"] == post_activity.data["object"]
@@ -993,8 +994,8 @@ defmodule Pleroma.Web.CommonAPITest do
other_user = insert(:user)
{:ok, activity} = CommonAPI.post(other_user, %{status: "cofe"})
- {:ok, %Activity{}} = CommonAPI.favorite(user, activity.id)
- assert {:ok, :already_liked} = CommonAPI.favorite(user, activity.id)
+ {:ok, %Activity{}} = CommonAPI.favorite(activity.id, user)
+ assert {:ok, :already_liked} = CommonAPI.favorite(activity.id, user)
end
end
@@ -1148,7 +1149,7 @@ defmodule Pleroma.Web.CommonAPITest do
}
)
- {:ok, favorite_activity} = CommonAPI.favorite(friend2, activity.id)
+ {:ok, favorite_activity} = CommonAPI.favorite(activity.id, friend2)
{:ok, repeat_activity} = CommonAPI.repeat(activity.id, friend1)
assert Repo.aggregate(
@@ -1171,8 +1172,8 @@ defmodule Pleroma.Web.CommonAPITest do
n.type == "mention" && n.activity_id == reply_activity.id
end)
- {:ok, _} = CommonAPI.add_mute(author, activity)
- assert CommonAPI.thread_muted?(author, activity)
+ {:ok, _} = CommonAPI.add_mute(activity, author)
+ assert CommonAPI.thread_muted?(activity, author)
assert Repo.aggregate(
from(n in Notification, where: n.seen == false and n.user_id == ^friend1.id),
@@ -1196,13 +1197,13 @@ defmodule Pleroma.Web.CommonAPITest do
end
test "add mute", %{user: user, activity: activity} do
- {:ok, _} = CommonAPI.add_mute(user, activity)
- assert CommonAPI.thread_muted?(user, activity)
+ {:ok, _} = CommonAPI.add_mute(activity, user)
+ assert CommonAPI.thread_muted?(activity, user)
end
test "add expiring mute", %{user: user, activity: activity} do
- {:ok, _} = CommonAPI.add_mute(user, activity, %{expires_in: 60})
- assert CommonAPI.thread_muted?(user, activity)
+ {:ok, _} = CommonAPI.add_mute(activity, user, %{expires_in: 60})
+ assert CommonAPI.thread_muted?(activity, user)
worker = Pleroma.Workers.MuteExpireWorker
args = %{"op" => "unmute_conversation", "user_id" => user.id, "activity_id" => activity.id}
@@ -1213,24 +1214,24 @@ defmodule Pleroma.Web.CommonAPITest do
)
assert :ok = perform_job(worker, args)
- refute CommonAPI.thread_muted?(user, activity)
+ refute CommonAPI.thread_muted?(activity, user)
end
test "remove mute", %{user: user, activity: activity} do
- CommonAPI.add_mute(user, activity)
- {:ok, _} = CommonAPI.remove_mute(user, activity)
- refute CommonAPI.thread_muted?(user, activity)
+ CommonAPI.add_mute(activity, user)
+ {:ok, _} = CommonAPI.remove_mute(activity, user)
+ refute CommonAPI.thread_muted?(activity, user)
end
test "remove mute by ids", %{user: user, activity: activity} do
- CommonAPI.add_mute(user, activity)
- {:ok, _} = CommonAPI.remove_mute(user.id, activity.id)
- refute CommonAPI.thread_muted?(user, activity)
+ CommonAPI.add_mute(activity, user)
+ {:ok, _} = CommonAPI.remove_mute(activity.id, user.id)
+ refute CommonAPI.thread_muted?(activity, user)
end
test "check that mutes can't be duplicate", %{user: user, activity: activity} do
- CommonAPI.add_mute(user, activity)
- {:error, _} = CommonAPI.add_mute(user, activity)
+ CommonAPI.add_mute(activity, user)
+ {:error, _} = CommonAPI.add_mute(activity, user)
end
end
@@ -1403,14 +1404,14 @@ defmodule Pleroma.Web.CommonAPITest do
end
test "add a reblog mute", %{muter: muter, muted: muted} do
- {:ok, _reblog_mute} = CommonAPI.hide_reblogs(muter, muted)
+ {:ok, _reblog_mute} = CommonAPI.hide_reblogs(muted, muter)
assert User.showing_reblogs?(muter, muted) == false
end
test "remove a reblog mute", %{muter: muter, muted: muted} do
- {:ok, _reblog_mute} = CommonAPI.hide_reblogs(muter, muted)
- {:ok, _reblog_mute} = CommonAPI.show_reblogs(muter, muted)
+ {:ok, _reblog_mute} = CommonAPI.hide_reblogs(muted, muter)
+ {:ok, _reblog_mute} = CommonAPI.show_reblogs(muted, muter)
assert User.showing_reblogs?(muter, muted) == true
end
@@ -1419,7 +1420,7 @@ defmodule Pleroma.Web.CommonAPITest do
describe "follow/2" do
test "directly follows a non-locked local user" do
[follower, followed] = insert_pair(:user)
- {:ok, follower, followed, _} = CommonAPI.follow(follower, followed)
+ {:ok, follower, followed, _} = CommonAPI.follow(followed, follower)
assert User.following?(follower, followed)
end
@@ -1428,24 +1429,24 @@ defmodule Pleroma.Web.CommonAPITest do
describe "unfollow/2" do
test "also unsubscribes a user" do
[follower, followed] = insert_pair(:user)
- {:ok, follower, followed, _} = CommonAPI.follow(follower, followed)
+ {:ok, follower, followed, _} = CommonAPI.follow(followed, follower)
{:ok, _subscription} = User.subscribe(follower, followed)
assert User.subscribed_to?(follower, followed)
- {:ok, follower} = CommonAPI.unfollow(follower, followed)
+ {:ok, follower} = CommonAPI.unfollow(followed, follower)
refute User.subscribed_to?(follower, followed)
end
test "also unpins a user" do
[follower, followed] = insert_pair(:user)
- {:ok, follower, followed, _} = CommonAPI.follow(follower, followed)
+ {:ok, follower, followed, _} = CommonAPI.follow(followed, follower)
{:ok, _endorsement} = User.endorse(follower, followed)
assert User.endorses?(follower, followed)
- {:ok, follower} = CommonAPI.unfollow(follower, followed)
+ {:ok, follower} = CommonAPI.unfollow(followed, follower)
refute User.endorses?(follower, followed)
end
@@ -1455,10 +1456,10 @@ defmodule Pleroma.Web.CommonAPITest do
followed = insert(:user, is_locked: true)
assert {:ok, follower, followed, %{id: activity_id, data: %{"state" => "pending"}}} =
- CommonAPI.follow(follower, followed)
+ CommonAPI.follow(followed, follower)
assert User.get_follow_state(follower, followed) == :follow_pending
- assert {:ok, follower} = CommonAPI.unfollow(follower, followed)
+ assert {:ok, follower} = CommonAPI.unfollow(followed, follower)
assert User.get_follow_state(follower, followed) == nil
assert %{id: ^activity_id, data: %{"state" => "cancelled"}} =
@@ -1477,10 +1478,10 @@ defmodule Pleroma.Web.CommonAPITest do
followed = insert(:user, is_locked: true, local: false)
assert {:ok, follower, followed, %{id: activity_id, data: %{"state" => "pending"}}} =
- CommonAPI.follow(follower, followed)
+ CommonAPI.follow(followed, follower)
assert User.get_follow_state(follower, followed) == :follow_pending
- assert {:ok, follower} = CommonAPI.unfollow(follower, followed)
+ assert {:ok, follower} = CommonAPI.unfollow(followed, follower)
assert User.get_follow_state(follower, followed) == nil
assert %{id: ^activity_id, data: %{"state" => "cancelled"}} =
@@ -1501,9 +1502,9 @@ defmodule Pleroma.Web.CommonAPITest do
follower = insert(:user)
follower_two = insert(:user)
- {:ok, _, _, follow_activity} = CommonAPI.follow(follower, user)
- {:ok, _, _, follow_activity_two} = CommonAPI.follow(follower, user)
- {:ok, _, _, follow_activity_three} = CommonAPI.follow(follower_two, user)
+ {:ok, _, _, follow_activity} = CommonAPI.follow(user, follower)
+ {:ok, _, _, follow_activity_two} = CommonAPI.follow(user, follower)
+ {:ok, _, _, follow_activity_three} = CommonAPI.follow(user, follower_two)
assert follow_activity.data["state"] == "pending"
assert follow_activity_two.data["state"] == "pending"
@@ -1521,9 +1522,9 @@ defmodule Pleroma.Web.CommonAPITest do
follower = insert(:user)
follower_two = insert(:user)
- {:ok, _, _, follow_activity} = CommonAPI.follow(follower, user)
- {:ok, _, _, follow_activity_two} = CommonAPI.follow(follower, user)
- {:ok, _, _, follow_activity_three} = CommonAPI.follow(follower_two, user)
+ {:ok, _, _, follow_activity} = CommonAPI.follow(user, follower)
+ {:ok, _, _, follow_activity_two} = CommonAPI.follow(user, follower)
+ {:ok, _, _, follow_activity_three} = CommonAPI.follow(user, follower_two)
assert follow_activity.data["state"] == "pending"
assert follow_activity_two.data["state"] == "pending"
@@ -1558,9 +1559,9 @@ defmodule Pleroma.Web.CommonAPITest do
object = Object.normalize(activity, fetch: false)
- {:ok, _, object} = CommonAPI.vote(other_user, object, [0])
+ {:ok, _, object} = CommonAPI.vote(object, other_user, [0])
- assert {:error, "Already voted"} == CommonAPI.vote(other_user, object, [1])
+ assert {:error, "Already voted"} == CommonAPI.vote(object, other_user, [1])
end
end
@@ -1694,7 +1695,7 @@ defmodule Pleroma.Web.CommonAPITest do
with_mock Pleroma.Web.Federator, publish: fn _ -> :ok end do
assert {:ok, %Activity{data: %{"type" => "Like"}} = activity} =
- CommonAPI.favorite(user, activity.id)
+ CommonAPI.favorite(activity.id, user)
assert Visibility.local_public?(activity)
refute called(Pleroma.Web.Federator.publish(activity))
@@ -1707,7 +1708,7 @@ defmodule Pleroma.Web.CommonAPITest do
{:ok, activity} = CommonAPI.post(other_user, %{status: "cofe", visibility: "local"})
- {:ok, %Activity{}} = CommonAPI.favorite(user, activity.id)
+ {:ok, %Activity{}} = CommonAPI.favorite(activity.id, user)
with_mock Pleroma.Web.Federator, publish: fn _ -> :ok end do
assert {:ok, activity} = CommonAPI.unfavorite(activity.id, user)
@@ -1752,7 +1753,7 @@ defmodule Pleroma.Web.CommonAPITest do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "foo1", spoiler_text: "title 1"})
- {:ok, updated} = CommonAPI.update(user, activity, %{status: "updated 2"})
+ {:ok, updated} = CommonAPI.update(activity, user, %{status: "updated 2"})
updated_object = Object.normalize(updated)
assert updated_object.data["content"] == "updated 2"
@@ -1766,7 +1767,7 @@ defmodule Pleroma.Web.CommonAPITest do
{:ok, activity} =
CommonAPI.post(user, %{status: "foo1", spoiler_text: "title 1", visibility: "private"})
- {:ok, updated} = CommonAPI.update(user, activity, %{status: "updated 2"})
+ {:ok, updated} = CommonAPI.update(activity, user, %{status: "updated 2"})
updated_object = Object.normalize(updated)
assert updated_object.data["content"] == "updated 2"
@@ -1783,7 +1784,7 @@ defmodule Pleroma.Web.CommonAPITest do
{:ok, activity} =
CommonAPI.post(user, %{status: "foo1", spoiler_text: "title 1 :#{emoji1}:"})
- {:ok, updated} = CommonAPI.update(user, activity, %{status: "updated 2 :#{emoji2}:"})
+ {:ok, updated} = CommonAPI.update(activity, user, %{status: "updated 2 :#{emoji2}:"})
updated_object = Object.normalize(updated)
assert updated_object.data["content"] == "updated 2 :#{emoji2}:"
@@ -1802,7 +1803,7 @@ defmodule Pleroma.Web.CommonAPITest do
with_mock Pleroma.Web.Federator,
publish: fn _p -> nil end do
- {:ok, updated} = CommonAPI.update(user, activity, %{status: "updated 2 :#{emoji2}:"})
+ {:ok, updated} = CommonAPI.update(activity, user, %{status: "updated 2 :#{emoji2}:"})
assert updated.data["object"]["content"] == "updated 2 :#{emoji2}:"
assert %{^emoji2 => _} = updated.data["object"]["emoji"]
@@ -1846,7 +1847,7 @@ defmodule Pleroma.Web.CommonAPITest do
assert reply.object.data["emoji"]["remoteemoji"] == remote_emoji_uri
{:ok, edit} =
- CommonAPI.update(user, reply, %{status: "reply mew mew", spoiler_text: ":remoteemoji:"})
+ CommonAPI.update(reply, user, %{status: "reply mew mew", spoiler_text: ":remoteemoji:"})
edited_note = Pleroma.Object.normalize(edit)
@@ -1862,7 +1863,7 @@ defmodule Pleroma.Web.CommonAPITest do
{:ok, activity} = CommonAPI.post(user, %{status: "foo1", spoiler_text: "updated 1"})
assert Object.normalize(activity).data["summary"] == "mewmew 1"
- {:ok, updated} = CommonAPI.update(user, activity, %{status: "updated 2"})
+ {:ok, updated} = CommonAPI.update(activity, user, %{status: "updated 2"})
updated_object = Object.normalize(updated)
assert updated_object.data["content"] == "mewmew 2"
@@ -1913,11 +1914,224 @@ defmodule Pleroma.Web.CommonAPITest do
end
test "it does not boost if group is blocking poster", %{poster: poster, group: group} do
- {:ok, _} = CommonAPI.block(group, poster)
+ {:ok, _} = CommonAPI.block(poster, group)
{:ok, post} = CommonAPI.post(poster, %{status: "hey @#{group.nickname}"})
announces = get_announces_of_object(post.object)
assert [] = announces
end
end
+
+ describe "Oban jobs are cancelled" do
+ setup do
+ clear_config([:instance, :federating], true)
+
+ local_user = insert(:user)
+
+ remote_one =
+ insert(:user, %{
+ local: false,
+ nickname: "nick1@domain.com",
+ ap_id: "https://domain.com/users/nick1",
+ inbox: "https://domain.com/users/nick1/inbox",
+ shared_inbox: "https://domain.com/inbox"
+ })
+
+ remote_two =
+ insert(:user, %{
+ local: false,
+ nickname: "nick2@example.com",
+ ap_id: "https://example.com/users/nick2",
+ inbox: "https://example.com/users/nick2/inbox",
+ shared_inbox: "https://example.com/inbox"
+ })
+
+ %{local_user: local_user, remote_one: remote_one, remote_two: remote_two}
+ end
+
+ test "when deleting posts", %{
+ local_user: local_user,
+ remote_one: remote_one,
+ remote_two: remote_two
+ } do
+ {:ok, _, _} = Pleroma.User.follow(remote_one, local_user)
+ {:ok, _, _} = Pleroma.User.follow(remote_two, local_user)
+
+ {:ok, %{data: %{"id" => ap_id}} = activity} =
+ CommonAPI.post(local_user, %{status: "Happy Friday everyone!"})
+
+ # Generate the publish_one jobs
+ ObanHelpers.perform_all()
+
+ publish_one_jobs =
+ all_enqueued()
+ |> Enum.filter(fn job ->
+ match?(
+ %{
+ state: "available",
+ queue: "federator_outgoing",
+ worker: "Pleroma.Workers.PublisherWorker",
+ args: %{"op" => "publish_one", "params" => %{"id" => ^ap_id}}
+ },
+ job
+ )
+ end)
+
+ assert length(publish_one_jobs) == 2
+
+ # The delete should have triggered cancelling the publish_one jobs
+ assert {:ok, _delete} = CommonAPI.delete(activity.id, local_user)
+
+ # all_enqueued/1 will not return cancelled jobs
+ cancelled_jobs =
+ Oban.Job
+ |> where([j], j.worker == "Pleroma.Workers.PublisherWorker")
+ |> where([j], j.state == "cancelled")
+ |> where([j], j.args["op"] == "publish_one")
+ |> where([j], j.args["params"]["id"] == ^ap_id)
+ |> Pleroma.Repo.all()
+
+ assert length(cancelled_jobs) == 2
+ end
+
+ test "when unfavoriting posts", %{
+ local_user: local_user,
+ remote_one: remote_user
+ } do
+ {:ok, activity} =
+ CommonAPI.post(remote_user, %{status: "I like turtles!"})
+
+ {:ok, %{data: %{"id" => ap_id}} = _favorite} =
+ CommonAPI.favorite(activity.id, local_user)
+
+ # Generate the publish_one jobs
+ ObanHelpers.perform_all()
+
+ publish_one_jobs =
+ all_enqueued()
+ |> Enum.filter(fn job ->
+ match?(
+ %{
+ state: "available",
+ queue: "federator_outgoing",
+ worker: "Pleroma.Workers.PublisherWorker",
+ args: %{"op" => "publish_one", "params" => %{"id" => ^ap_id}}
+ },
+ job
+ )
+ end)
+
+ assert length(publish_one_jobs) == 1
+
+ # The unfavorite should have triggered cancelling the publish_one jobs
+ assert {:ok, _unfavorite} = CommonAPI.unfavorite(activity.id, local_user)
+
+ # all_enqueued/1 will not return cancelled jobs
+ cancelled_jobs =
+ Oban.Job
+ |> where([j], j.worker == "Pleroma.Workers.PublisherWorker")
+ |> where([j], j.state == "cancelled")
+ |> where([j], j.args["op"] == "publish_one")
+ |> where([j], j.args["params"]["id"] == ^ap_id)
+ |> Pleroma.Repo.all()
+
+ assert length(cancelled_jobs) == 1
+ end
+
+ test "when unboosting posts", %{
+ local_user: local_user,
+ remote_one: remote_one,
+ remote_two: remote_two
+ } do
+ {:ok, _, _} = Pleroma.User.follow(remote_one, local_user)
+ {:ok, _, _} = Pleroma.User.follow(remote_two, local_user)
+
+ {:ok, activity} =
+ CommonAPI.post(remote_one, %{status: "This is an unpleasant post"})
+
+ {:ok, %{data: %{"id" => ap_id}} = _repeat} =
+ CommonAPI.repeat(activity.id, local_user)
+
+ # Generate the publish_one jobs
+ ObanHelpers.perform_all()
+
+ publish_one_jobs =
+ all_enqueued()
+ |> Enum.filter(fn job ->
+ match?(
+ %{
+ state: "available",
+ queue: "federator_outgoing",
+ worker: "Pleroma.Workers.PublisherWorker",
+ args: %{"op" => "publish_one", "params" => %{"id" => ^ap_id}}
+ },
+ job
+ )
+ end)
+
+ assert length(publish_one_jobs) == 2
+
+ # The unrepeat should have triggered cancelling the publish_one jobs
+ assert {:ok, _unfavorite} = CommonAPI.unrepeat(activity.id, local_user)
+
+ # all_enqueued/1 will not return cancelled jobs
+ cancelled_jobs =
+ Oban.Job
+ |> where([j], j.worker == "Pleroma.Workers.PublisherWorker")
+ |> where([j], j.state == "cancelled")
+ |> where([j], j.args["op"] == "publish_one")
+ |> where([j], j.args["params"]["id"] == ^ap_id)
+ |> Pleroma.Repo.all()
+
+ assert length(cancelled_jobs) == 2
+ end
+
+ test "when unreacting to posts", %{
+ local_user: local_user,
+ remote_one: remote_one,
+ remote_two: remote_two
+ } do
+ {:ok, _, _} = Pleroma.User.follow(remote_one, local_user)
+ {:ok, _, _} = Pleroma.User.follow(remote_two, local_user)
+
+ {:ok, activity} =
+ CommonAPI.post(remote_one, %{status: "Gang gang!!!!"})
+
+ {:ok, %{data: %{"id" => ap_id}} = _react} =
+ CommonAPI.react_with_emoji(activity.id, local_user, "👍")
+
+ # Generate the publish_one jobs
+ ObanHelpers.perform_all()
+
+ publish_one_jobs =
+ all_enqueued()
+ |> Enum.filter(fn job ->
+ match?(
+ %{
+ state: "available",
+ queue: "federator_outgoing",
+ worker: "Pleroma.Workers.PublisherWorker",
+ args: %{"op" => "publish_one", "params" => %{"id" => ^ap_id}}
+ },
+ job
+ )
+ end)
+
+ assert length(publish_one_jobs) == 2
+
+ # The unreact should have triggered cancelling the publish_one jobs
+ assert {:ok, _unreact} = CommonAPI.unreact_with_emoji(activity.id, local_user, "👍")
+
+ # all_enqueued/1 will not return cancelled jobs
+ cancelled_jobs =
+ Oban.Job
+ |> where([j], j.worker == "Pleroma.Workers.PublisherWorker")
+ |> where([j], j.state == "cancelled")
+ |> where([j], j.args["op"] == "publish_one")
+ |> where([j], j.args["params"]["id"] == ^ap_id)
+ |> Pleroma.Repo.all()
+
+ assert length(cancelled_jobs) == 2
+ end
+ end
end
diff --git a/test/pleroma/web/feed/tag_controller_test.exs b/test/pleroma/web/feed/tag_controller_test.exs
index 58ab8f137..7d196b228 100644
--- a/test/pleroma/web/feed/tag_controller_test.exs
+++ b/test/pleroma/web/feed/tag_controller_test.exs
@@ -55,11 +55,11 @@ defmodule Pleroma.Web.Feed.TagControllerTest do
xml = parse(response)
- assert xpath(xml, ~x"//feed/title/text()") == '#pleromaart'
+ assert xpath(xml, ~x"//feed/title/text()") == ~c"#pleromaart"
assert xpath(xml, ~x"//feed/entry/title/text()"l) == [
- '42 This is :moominmamm...',
- 'yeah #PleromaArt'
+ ~c"42 This is :moominmamm...",
+ ~c"yeah #PleromaArt"
]
assert xpath(xml, ~x"//feed/entry/author/name/text()"ls) == [user.nickname, user.nickname]
@@ -73,10 +73,10 @@ defmodule Pleroma.Web.Feed.TagControllerTest do
resp = response(conn, 200)
xml = parse(resp)
- assert xpath(xml, ~x"//feed/title/text()") == '#pleromaart'
+ assert xpath(xml, ~x"//feed/title/text()") == ~c"#pleromaart"
assert xpath(xml, ~x"//feed/entry/title/text()"l) == [
- 'yeah #PleromaArt'
+ ~c"yeah #PleromaArt"
]
end
@@ -120,20 +120,20 @@ defmodule Pleroma.Web.Feed.TagControllerTest do
|> response(200)
xml = parse(response)
- assert xpath(xml, ~x"//channel/title/text()") == '#pleromaart'
+ assert xpath(xml, ~x"//channel/title/text()") == ~c"#pleromaart"
assert xpath(xml, ~x"//channel/description/text()"s) ==
"These are public toots tagged with #pleromaart. You can interact with them if you have an account anywhere in the fediverse."
assert xpath(xml, ~x"//channel/link/text()") ==
- '#{Pleroma.Web.Endpoint.url()}/tags/pleromaart.rss'
+ ~c"#{Pleroma.Web.Endpoint.url()}/tags/pleromaart.rss"
assert xpath(xml, ~x"//channel/webfeeds:logo/text()") ==
- '#{Pleroma.Web.Endpoint.url()}/static/logo.svg'
+ ~c"#{Pleroma.Web.Endpoint.url()}/static/logo.svg"
assert xpath(xml, ~x"//channel/item/title/text()"l) == [
- '42 This is :moominmamm...',
- 'yeah #PleromaArt'
+ ~c"42 This is :moominmamm...",
+ ~c"yeah #PleromaArt"
]
assert xpath(xml, ~x"//channel/item/pubDate/text()"sl) == [
@@ -160,7 +160,7 @@ defmodule Pleroma.Web.Feed.TagControllerTest do
|> response(200)
xml = parse(response)
- assert xpath(xml, ~x"//channel/title/text()") == '#pleromaart'
+ assert xpath(xml, ~x"//channel/title/text()") == ~c"#pleromaart"
assert xpath(xml, ~x"//channel/description/text()"s) ==
"These are public toots tagged with #pleromaart. You can interact with them if you have an account anywhere in the fediverse."
@@ -174,10 +174,10 @@ defmodule Pleroma.Web.Feed.TagControllerTest do
resp = response(conn, 200)
xml = parse(resp)
- assert xpath(xml, ~x"//channel/title/text()") == '#pleromaart'
+ assert xpath(xml, ~x"//channel/title/text()") == ~c"#pleromaart"
assert xpath(xml, ~x"//channel/item/title/text()"l) == [
- 'yeah #PleromaArt'
+ ~c"yeah #PleromaArt"
]
end
diff --git a/test/pleroma/web/feed/user_controller_test.exs b/test/pleroma/web/feed/user_controller_test.exs
index d3c4108de..1c17d47b4 100644
--- a/test/pleroma/web/feed/user_controller_test.exs
+++ b/test/pleroma/web/feed/user_controller_test.exs
@@ -88,7 +88,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|> SweetXml.parse()
|> SweetXml.xpath(~x"//entry/title/text()"l)
- assert activity_titles == ['Won\'t, didn\'...', '2hu', '2hu & as']
+ assert activity_titles == [~c"Won't, didn'...", ~c"2hu", ~c"2hu & as"]
assert resp =~ FeedView.escape(object.data["content"])
assert resp =~ FeedView.escape(object.data["summary"])
assert resp =~ FeedView.escape(object.data["context"])
@@ -104,7 +104,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|> SweetXml.parse()
|> SweetXml.xpath(~x"//entry/title/text()"l)
- assert activity_titles == ['2hu & as']
+ assert activity_titles == [~c"2hu & as"]
end
test "gets a rss feed", %{conn: conn, user: user, object: object, max_id: max_id} do
@@ -119,7 +119,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|> SweetXml.parse()
|> SweetXml.xpath(~x"//item/title/text()"l)
- assert activity_titles == ['Won\'t, didn\'...', '2hu', '2hu & as']
+ assert activity_titles == [~c"Won't, didn'...", ~c"2hu", ~c"2hu & as"]
assert resp =~ FeedView.escape(object.data["content"])
assert resp =~ FeedView.escape(object.data["summary"])
assert resp =~ FeedView.escape(object.data["context"])
@@ -135,7 +135,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|> SweetXml.parse()
|> SweetXml.xpath(~x"//item/title/text()"l)
- assert activity_titles == ['2hu & as']
+ assert activity_titles == [~c"2hu & as"]
end
test "returns 404 for a missing feed", %{conn: conn} do
@@ -167,7 +167,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|> SweetXml.xpath(~x"//entry/title/text()"l)
|> Enum.sort()
- assert activity_titles == ['public', 'unlisted']
+ assert activity_titles == [~c"public", ~c"unlisted"]
end
test "returns 404 when the user is remote", %{conn: conn} do
@@ -208,7 +208,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|> SweetXml.parse()
|> SweetXml.xpath(~x"//entry/title/text()"l)
- assert activity_titles == ['Won\'t, didn\'...', '2hu', '2hu & as']
+ assert activity_titles == [~c"Won't, didn'...", ~c"2hu", ~c"2hu & as"]
assert resp =~ FeedView.escape(object.data["content"])
assert resp =~ FeedView.escape(object.data["summary"])
assert resp =~ FeedView.escape(object.data["context"])
diff --git a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs
index aa7726a9c..54f6818bd 100644
--- a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs
@@ -1120,7 +1120,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|> json_response_and_validate_schema(200)
# Follow the user, then the pinned status can be seen
- CommonAPI.follow(reader, user)
+ CommonAPI.follow(user, reader)
ObanHelpers.perform_all()
assert [%{"id" => ^activity_id, "pinned" => true}] =
@@ -2118,7 +2118,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
test "pin account", %{user: user, conn: conn} do
%{id: id1} = other_user1 = insert(:user)
- CommonAPI.follow(user, other_user1)
+ CommonAPI.follow(other_user1, user)
assert %{"id" => ^id1, "endorsed" => true} =
conn
@@ -2136,7 +2136,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
test "unpin account", %{user: user, conn: conn} do
%{id: id1} = other_user1 = insert(:user)
- CommonAPI.follow(user, other_user1)
+ CommonAPI.follow(other_user1, user)
User.endorse(user, other_user1)
assert %{"id" => ^id1, "endorsed" => false} =
@@ -2156,8 +2156,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
%{id: id1} = other_user1 = insert(:user)
%{id: id2} = other_user2 = insert(:user)
- CommonAPI.follow(user, other_user1)
- CommonAPI.follow(user, other_user2)
+ CommonAPI.follow(other_user1, user)
+ CommonAPI.follow(other_user2, user)
conn
|> put_req_header("content-type", "application/json")
@@ -2172,13 +2172,62 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
end
end
+ describe "familiar followers" do
+ setup do: oauth_access(["read:follows"])
+
+ test "fetch user familiar followers", %{user: user, conn: conn} do
+ %{id: id1} = other_user1 = insert(:user)
+ %{id: id2} = other_user2 = insert(:user)
+ _ = insert(:user)
+
+ User.follow(user, other_user1)
+ User.follow(other_user1, other_user2)
+
+ assert [%{"accounts" => [%{"id" => ^id1}], "id" => ^id2}] =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> get("/api/v1/accounts/familiar_followers?id[]=#{id2}")
+ |> json_response_and_validate_schema(200)
+ end
+
+ test "returns empty array if followers are hidden", %{user: user, conn: conn} do
+ other_user1 = insert(:user, hide_follows: true)
+ %{id: id2} = other_user2 = insert(:user)
+ _ = insert(:user)
+
+ User.follow(user, other_user1)
+ User.follow(other_user1, other_user2)
+
+ assert [%{"accounts" => [], "id" => ^id2}] =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> get("/api/v1/accounts/familiar_followers?id[]=#{id2}")
+ |> json_response_and_validate_schema(200)
+ end
+
+ test "it respects hide_followers", %{user: user, conn: conn} do
+ other_user1 = insert(:user)
+ %{id: id2} = other_user2 = insert(:user, hide_followers: true)
+ _ = insert(:user)
+
+ User.follow(user, other_user1)
+ User.follow(other_user1, other_user2)
+
+ assert [%{"accounts" => [], "id" => ^id2}] =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> get("/api/v1/accounts/familiar_followers?id[]=#{id2}")
+ |> json_response_and_validate_schema(200)
+ end
+ end
+
describe "remove from followers" do
setup do: oauth_access(["follow"])
test "removing user from followers", %{conn: conn, user: user} do
%{id: other_user_id} = other_user = insert(:user)
- CommonAPI.follow(other_user, user)
+ CommonAPI.follow(user, other_user)
assert %{"id" => ^other_user_id, "followed_by" => false} =
conn
@@ -2191,7 +2240,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
test "removing remote user from followers", %{conn: conn, user: user} do
%{id: other_user_id} = other_user = insert(:user, local: false)
- CommonAPI.follow(other_user, user)
+ CommonAPI.follow(user, other_user)
assert User.following?(other_user, user)
diff --git a/test/pleroma/web/mastodon_api/controllers/follow_request_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/follow_request_controller_test.exs
index ff01b549c..b7c7ccae0 100644
--- a/test/pleroma/web/mastodon_api/controllers/follow_request_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/follow_request_controller_test.exs
@@ -20,7 +20,7 @@ defmodule Pleroma.Web.MastodonAPI.FollowRequestControllerTest do
test "/api/v1/follow_requests works", %{user: user, conn: conn} do
other_user = insert(:user)
- {:ok, _, _, _activity} = CommonAPI.follow(other_user, user)
+ {:ok, _, _, _activity} = CommonAPI.follow(user, other_user)
{:ok, other_user, user} = User.follow(other_user, user, :follow_pending)
assert User.following?(other_user, user) == false
@@ -34,7 +34,7 @@ defmodule Pleroma.Web.MastodonAPI.FollowRequestControllerTest do
test "/api/v1/follow_requests/:id/authorize works", %{user: user, conn: conn} do
other_user = insert(:user)
- {:ok, _, _, _activity} = CommonAPI.follow(other_user, user)
+ {:ok, _, _, _activity} = CommonAPI.follow(user, other_user)
{:ok, other_user, user} = User.follow(other_user, user, :follow_pending)
user = User.get_cached_by_id(user.id)
@@ -56,7 +56,7 @@ defmodule Pleroma.Web.MastodonAPI.FollowRequestControllerTest do
test "/api/v1/follow_requests/:id/reject works", %{user: user, conn: conn} do
other_user = insert(:user)
- {:ok, _, _, _activity} = CommonAPI.follow(other_user, user)
+ {:ok, _, _, _activity} = CommonAPI.follow(user, other_user)
user = User.get_cached_by_id(user.id)
diff --git a/test/pleroma/web/mastodon_api/controllers/media_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/media_controller_test.exs
index b92fd8afa..4adbaa640 100644
--- a/test/pleroma/web/mastodon_api/controllers/media_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/media_controller_test.exs
@@ -76,6 +76,7 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
end
test "/api/v2/media, upload_limit", %{conn: conn, user: user} do
+ clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
desc = "Description of the binary"
upload_limit = Config.get([:instance, :upload_limit]) * 8 + 8
diff --git a/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs
index 350b935d7..8fc22dde1 100644
--- a/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs
@@ -148,7 +148,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
%{user: user, conn: conn} = oauth_access(["read:notifications"])
blocker = insert(:user)
- {:ok, _} = CommonAPI.block(blocker, user)
+ {:ok, _} = CommonAPI.block(user, blocker)
{:ok, activity} = CommonAPI.post(blocker, %{status: "hi @#{user.nickname}"})
{:ok, [_notification]} = Notification.create_notifications(activity)
@@ -326,10 +326,10 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
{:ok, private_activity} = CommonAPI.post(other_user, %{status: ".", visibility: "private"})
- {:ok, _} = CommonAPI.favorite(user, public_activity.id)
- {:ok, _} = CommonAPI.favorite(user, direct_activity.id)
- {:ok, _} = CommonAPI.favorite(user, unlisted_activity.id)
- {:ok, _} = CommonAPI.favorite(user, private_activity.id)
+ {:ok, _} = CommonAPI.favorite(public_activity.id, user)
+ {:ok, _} = CommonAPI.favorite(direct_activity.id, user)
+ {:ok, _} = CommonAPI.favorite(unlisted_activity.id, user)
+ {:ok, _} = CommonAPI.favorite(private_activity.id, user)
activity_ids =
conn
@@ -414,7 +414,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
in_reply_to_status_id: activity.id
})
- {:ok, _favorite} = CommonAPI.favorite(user, reply.id)
+ {:ok, _favorite} = CommonAPI.favorite(reply.id, user)
activity_ids =
conn
@@ -432,9 +432,9 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
{:ok, mention_activity} = CommonAPI.post(other_user, %{status: "hey @#{user.nickname}"})
{:ok, create_activity} = CommonAPI.post(user, %{status: "hey"})
- {:ok, favorite_activity} = CommonAPI.favorite(other_user, create_activity.id)
+ {:ok, favorite_activity} = CommonAPI.favorite(create_activity.id, other_user)
{:ok, reblog_activity} = CommonAPI.repeat(create_activity.id, other_user)
- {:ok, _, _, follow_activity} = CommonAPI.follow(other_user, user)
+ {:ok, _, _, follow_activity} = CommonAPI.follow(user, other_user)
mention_notification_id = get_notification_id_by_activity(mention_activity)
favorite_notification_id = get_notification_id_by_activity(favorite_activity)
@@ -470,9 +470,9 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
{:ok, mention_activity} = CommonAPI.post(other_user, %{status: "hey @#{user.nickname}"})
{:ok, create_activity} = CommonAPI.post(user, %{status: "hey"})
- {:ok, favorite_activity} = CommonAPI.favorite(other_user, create_activity.id)
+ {:ok, favorite_activity} = CommonAPI.favorite(create_activity.id, other_user)
{:ok, reblog_activity} = CommonAPI.repeat(create_activity.id, other_user)
- {:ok, _, _, follow_activity} = CommonAPI.follow(other_user, user)
+ {:ok, _, _, follow_activity} = CommonAPI.follow(user, other_user)
mention_notification_id = get_notification_id_by_activity(mention_activity)
favorite_notification_id = get_notification_id_by_activity(favorite_activity)
@@ -517,9 +517,9 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
{:ok, _activity} = CommonAPI.post(other_user, %{status: "hey @#{user.nickname}"})
{:ok, create_activity} = CommonAPI.post(user, %{status: "hey"})
- {:ok, _activity} = CommonAPI.favorite(other_user, create_activity.id)
+ {:ok, _activity} = CommonAPI.favorite(create_activity.id, other_user)
{:ok, _activity} = CommonAPI.repeat(create_activity.id, other_user)
- {:ok, _, _, follow_activity} = CommonAPI.follow(other_user, user)
+ {:ok, _, _, follow_activity} = CommonAPI.follow(user, other_user)
follow_notification_id = get_notification_id_by_activity(follow_activity)
@@ -578,7 +578,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
%{user: user, conn: conn} = oauth_access(["read:notifications"])
user2 = insert(:user)
- {:ok, _, _, _} = CommonAPI.follow(user, user2)
+ {:ok, _, _, _} = CommonAPI.follow(user2, user)
{:ok, _} = CommonAPI.post(user2, %{status: "hey @#{user.nickname}"})
ret_conn = get(conn, "/api/v1/notifications")
@@ -596,7 +596,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
%{user: user, conn: conn} = oauth_access(["read:notifications"])
user2 = insert(:user)
- {:ok, _, _, _} = CommonAPI.follow(user, user2)
+ {:ok, _, _, _} = CommonAPI.follow(user2, user)
{:ok, _} = CommonAPI.post(user2, %{status: "hey @#{user.nickname}"})
ret_conn = get(conn, "/api/v1/notifications")
@@ -614,7 +614,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
%{user: user, conn: conn} = oauth_access(["read:notifications"])
user2 = insert(:user)
- {:ok, _, _, _} = CommonAPI.follow(user, user2)
+ {:ok, _, _, _} = CommonAPI.follow(user2, user)
{:ok, _} = CommonAPI.post(user2, %{status: "hey @#{user.nickname}"})
ret_conn = get(conn, "/api/v1/notifications")
diff --git a/test/pleroma/web/mastodon_api/controllers/scheduled_activity_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/scheduled_activity_controller_test.exs
index 632242221..2d6b2aee2 100644
--- a/test/pleroma/web/mastodon_api/controllers/scheduled_activity_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/scheduled_activity_controller_test.exs
@@ -3,6 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do
+ use Oban.Testing, repo: Pleroma.Repo
use Pleroma.Web.ConnCase, async: true
alias Pleroma.Repo
@@ -78,7 +79,7 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do
}
)
- job = Repo.one(from(j in Oban.Job, where: j.queue == "scheduled_activities"))
+ job = Repo.one(from(j in Oban.Job, where: j.queue == "federator_outgoing"))
assert job.args == %{"activity_id" => scheduled_activity.id}
assert DateTime.truncate(job.scheduled_at, :second) == to_datetime(scheduled_at)
@@ -124,9 +125,11 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do
}
)
- job = Repo.one(from(j in Oban.Job, where: j.queue == "scheduled_activities"))
-
- assert job.args == %{"activity_id" => scheduled_activity.id}
+ assert_enqueued(
+ worker: Pleroma.Workers.ScheduledActivityWorker,
+ args: %{"activity_id" => scheduled_activity.id},
+ queue: :federator_outgoing
+ )
res_conn =
conn
@@ -135,7 +138,11 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do
assert %{} = json_response_and_validate_schema(res_conn, 200)
refute Repo.get(ScheduledActivity, scheduled_activity.id)
- refute Repo.get(Oban.Job, job.id)
+
+ refute_enqueued(
+ worker: Pleroma.Workers.ScheduledActivityWorker,
+ args: %{"activity_id" => scheduled_activity.id}
+ )
res_conn =
conn
diff --git a/test/pleroma/web/mastodon_api/controllers/search_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/search_controller_test.exs
index ad4144da4..d38767c96 100644
--- a/test/pleroma/web/mastodon_api/controllers/search_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/search_controller_test.exs
@@ -130,7 +130,6 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
assert [] = results["statuses"]
end
- @tag capture_log: true
test "constructs hashtags from search query", %{conn: conn} do
results =
conn
diff --git a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
index 80c1ed099..904bf1471 100644
--- a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
@@ -235,6 +235,16 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
assert Activity.get_in_reply_to_activity(activity).id == replied_to.id
end
+ test "replying to a deleted status", %{user: user, conn: conn} do
+ {:ok, status} = CommonAPI.post(user, %{status: "cofe"})
+ {:ok, _deleted_status} = CommonAPI.delete(status.id, user)
+
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => status.id})
+ |> json_response_and_validate_schema(422)
+ end
+
test "replying to a direct message with visibility other than direct", %{
user: user,
conn: conn
@@ -1346,7 +1356,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
user1 = insert(:user)
user2 = insert(:user)
user3 = insert(:user)
- {:ok, _} = CommonAPI.favorite(user2, activity.id)
+ {:ok, _} = CommonAPI.favorite(activity.id, user2)
{:ok, _bookmark} = Pleroma.Bookmark.create(user2.id, activity.id)
{:ok, reblog_activity1} = CommonAPI.repeat(activity.id, user1)
{:ok, _} = CommonAPI.repeat(activity.id, user2)
@@ -1473,7 +1483,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
test "unfavorites a status and returns it", %{user: user, conn: conn} do
activity = insert(:note_activity)
- {:ok, _} = CommonAPI.favorite(user, activity.id)
+ {:ok, _} = CommonAPI.favorite(activity.id, user)
conn =
conn
@@ -1761,7 +1771,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
end
test "cannot mute already muted conversation", %{conn: conn, user: user, activity: activity} do
- {:ok, _} = CommonAPI.add_mute(user, activity)
+ {:ok, _} = CommonAPI.add_mute(activity, user)
conn =
conn
@@ -1774,7 +1784,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
end
test "unmute conversation", %{conn: conn, user: user, activity: activity} do
- {:ok, _} = CommonAPI.add_mute(user, activity)
+ {:ok, _} = CommonAPI.add_mute(activity, user)
id_str = to_string(activity.id)
@@ -1849,7 +1859,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
test "returns users who have favorited the status", %{conn: conn, activity: activity} do
other_user = insert(:user)
- {:ok, _} = CommonAPI.favorite(other_user, activity.id)
+ {:ok, _} = CommonAPI.favorite(activity.id, other_user)
response =
conn
@@ -1880,7 +1890,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
other_user = insert(:user)
{:ok, _user_relationship} = User.block(user, other_user)
- {:ok, _} = CommonAPI.favorite(other_user, activity.id)
+ {:ok, _} = CommonAPI.favorite(activity.id, other_user)
response =
conn
@@ -1892,7 +1902,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
test "does not fail on an unauthenticated request", %{activity: activity} do
other_user = insert(:user)
- {:ok, _} = CommonAPI.favorite(other_user, activity.id)
+ {:ok, _} = CommonAPI.favorite(activity.id, other_user)
response =
build_conn()
@@ -1912,7 +1922,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
visibility: "direct"
})
- {:ok, _} = CommonAPI.favorite(other_user, activity.id)
+ {:ok, _} = CommonAPI.favorite(activity.id, other_user)
favourited_by_url = "/api/v1/statuses/#{activity.id}/favourited_by"
@@ -1943,7 +1953,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
clear_config([:instance, :show_reactions], false)
other_user = insert(:user)
- {:ok, _} = CommonAPI.favorite(other_user, activity.id)
+ {:ok, _} = CommonAPI.favorite(activity.id, other_user)
response =
conn
@@ -2086,9 +2096,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
{:ok, second_post} = CommonAPI.post(other_user, %{status: "bla"})
{:ok, third_post} = CommonAPI.post(other_user, %{status: "bla"})
- {:ok, _first_favorite} = CommonAPI.favorite(user, third_post.id)
- {:ok, _second_favorite} = CommonAPI.favorite(user, first_post.id)
- {:ok, third_favorite} = CommonAPI.favorite(user, second_post.id)
+ {:ok, _first_favorite} = CommonAPI.favorite(third_post.id, user)
+ {:ok, _second_favorite} = CommonAPI.favorite(first_post.id, user)
+ {:ok, third_favorite} = CommonAPI.favorite(second_post.id, user)
result =
conn
@@ -2124,7 +2134,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
{:ok, _} = CommonAPI.post(other_user, %{status: "bla"})
{:ok, activity} = CommonAPI.post(other_user, %{status: "trees are happy"})
- {:ok, last_like} = CommonAPI.favorite(user, activity.id)
+ {:ok, last_like} = CommonAPI.favorite(activity.id, user)
first_conn = get(conn, "/api/v1/favourites")
@@ -2140,7 +2150,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
status: "Trees Are Never Sad Look At Them Every Once In Awhile They're Quite Beautiful."
})
- {:ok, _} = CommonAPI.favorite(user, second_activity.id)
+ {:ok, _} = CommonAPI.favorite(second_activity.id, user)
second_conn = get(conn, "/api/v1/favourites?since_id=#{last_like.id}")
diff --git a/test/pleroma/web/mastodon_api/controllers/suggestion_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/suggestion_controller_test.exs
index c0f3d5a2a..01c3384e7 100644
--- a/test/pleroma/web/mastodon_api/controllers/suggestion_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/suggestion_controller_test.exs
@@ -47,7 +47,7 @@ defmodule Pleroma.Web.MastodonAPI.SuggestionControllerTest do
test "returns v2 suggestions excluding blocked accounts", %{conn: conn, user: blocker} do
blocked = insert(:user, is_suggested: true)
- {:ok, _} = CommonAPI.block(blocker, blocked)
+ {:ok, _} = CommonAPI.block(blocked, blocker)
res =
conn
@@ -59,7 +59,7 @@ defmodule Pleroma.Web.MastodonAPI.SuggestionControllerTest do
test "returns v2 suggestions excluding followed accounts", %{conn: conn, user: follower} do
followed = insert(:user, is_suggested: true)
- {:ok, _, _, _} = CommonAPI.follow(follower, followed)
+ {:ok, _, _, _} = CommonAPI.follow(followed, follower)
res =
conn
diff --git a/test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs
index c120dd53c..4d646509c 100644
--- a/test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs
@@ -152,7 +152,6 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
end
describe "public" do
- @tag capture_log: true
test "the public timeline", %{conn: conn} do
user = insert(:user)
@@ -791,7 +790,6 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
describe "hashtag" do
setup do: oauth_access(["n/a"])
- @tag capture_log: true
test "hashtag timeline", %{conn: conn} do
following = insert(:user)
diff --git a/test/pleroma/web/mastodon_api/views/account_view_test.exs b/test/pleroma/web/mastodon_api/views/account_view_test.exs
index 8dcdaf447..f0711fa0d 100644
--- a/test/pleroma/web/mastodon_api/views/account_view_test.exs
+++ b/test/pleroma/web/mastodon_api/views/account_view_test.exs
@@ -436,7 +436,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
{:ok, other_user, user} = User.follow(other_user, user)
{:ok, _subscription} = User.subscribe(user, other_user)
{:ok, _user_relationships} = User.mute(user, other_user, %{notifications: true})
- {:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, other_user)
+ {:ok, _reblog_mute} = CommonAPI.hide_reblogs(other_user, user)
expected =
Map.merge(
@@ -493,7 +493,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
user = insert(:user)
other_user = insert(:user, is_locked: true)
- {:ok, user, other_user, _} = CommonAPI.follow(user, other_user)
+ {:ok, user, other_user, _} = CommonAPI.follow(other_user, user)
user = User.get_cached_by_id(user.id)
other_user = User.get_cached_by_id(other_user.id)
@@ -547,8 +547,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
})
other_user = insert(:user)
- {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user)
- {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
+ {:ok, user, other_user, _activity} = CommonAPI.follow(other_user, user)
+ {:ok, _other_user, user, _activity} = CommonAPI.follow(user, other_user)
assert %{
followers_count: 0,
@@ -560,8 +560,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
test "shows when follows/followers are hidden" do
user = insert(:user, hide_followers: true, hide_follows: true)
other_user = insert(:user)
- {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user)
- {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
+ {:ok, user, other_user, _activity} = CommonAPI.follow(other_user, user)
+ {:ok, _other_user, user, _activity} = CommonAPI.follow(user, other_user)
assert %{
followers_count: 1,
@@ -573,11 +573,11 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
test "shows actual follower/following count to the account owner" do
user = insert(:user, hide_followers: true, hide_follows: true)
other_user = insert(:user)
- {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user)
+ {:ok, user, other_user, _activity} = CommonAPI.follow(other_user, user)
assert User.following?(user, other_user)
assert Pleroma.FollowingRelationship.follower_count(other_user) == 1
- {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
+ {:ok, _other_user, user, _activity} = CommonAPI.follow(user, other_user)
assert %{
followers_count: 1,
@@ -684,7 +684,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
AccountView.render("show.json", %{user: user, for: user})
other_user = insert(:user)
- {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
+ {:ok, _other_user, user, _activity} = CommonAPI.follow(user, other_user)
assert %{follow_requests_count: 0} =
AccountView.render("show.json", %{user: user, for: user})
@@ -696,7 +696,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
other_user = insert(:user)
- {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
+ {:ok, _other_user, user, _activity} = CommonAPI.follow(user, other_user)
assert %{locked: true, follow_requests_count: 1} =
AccountView.render("show.json", %{user: user, for: user})
@@ -708,7 +708,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
other_user = insert(:user)
- {:ok, other_user, user, _activity} = CommonAPI.follow(other_user, user)
+ {:ok, other_user, user, _activity} = CommonAPI.follow(user, other_user)
assert %{locked: true, follow_requests_count: 1} =
AccountView.render("show.json", %{user: user, for: user})
@@ -725,7 +725,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
other_user = insert(:user)
- {:ok, other_user, user, _activity} = CommonAPI.follow(other_user, user)
+ {:ok, other_user, user, _activity} = CommonAPI.follow(user, other_user)
assert %{locked: true, follow_requests_count: 1} =
AccountView.render("show.json", %{user: user, for: user})
@@ -742,7 +742,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
other_user = insert(:user)
- {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
+ {:ok, _other_user, user, _activity} = CommonAPI.follow(user, other_user)
{:ok, user} = User.update_and_set_cache(user, %{is_locked: false})
diff --git a/test/pleroma/web/mastodon_api/views/notification_view_test.exs b/test/pleroma/web/mastodon_api/views/notification_view_test.exs
index 47425d2a9..fae672871 100644
--- a/test/pleroma/web/mastodon_api/views/notification_view_test.exs
+++ b/test/pleroma/web/mastodon_api/views/notification_view_test.exs
@@ -93,7 +93,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
user = insert(:user)
another_user = insert(:user)
{:ok, create_activity} = CommonAPI.post(user, %{status: "hey"})
- {:ok, favorite_activity} = CommonAPI.favorite(another_user, create_activity.id)
+ {:ok, favorite_activity} = CommonAPI.favorite(create_activity.id, another_user)
{:ok, [notification]} = Notification.create_notifications(favorite_activity)
create_activity = Activity.get_by_id(create_activity.id)
@@ -132,7 +132,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
test "Follow notification" do
follower = insert(:user)
followed = insert(:user)
- {:ok, follower, followed, _activity} = CommonAPI.follow(follower, followed)
+ {:ok, follower, followed, _activity} = CommonAPI.follow(followed, follower)
notification = Notification |> Repo.one() |> Repo.preload(:activity)
expected = %{
@@ -290,7 +290,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
{:ok, activity} = CommonAPI.post(user, %{status: "mew"})
{:ok, _} = CommonAPI.repeat(activity.id, repeat_user)
- {:ok, update} = CommonAPI.update(user, activity, %{status: "mew mew"})
+ {:ok, update} = CommonAPI.update(activity, user, %{status: "mew mew"})
user = Pleroma.User.get_by_ap_id(user.ap_id)
activity = Pleroma.Activity.normalize(activity)
@@ -316,7 +316,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
{:ok, _} = Pleroma.UserRelationship.create_mute(user, another_user)
{:ok, create_activity} = CommonAPI.post(user, %{status: "hey"})
- {:ok, favorite_activity} = CommonAPI.favorite(another_user, create_activity.id)
+ {:ok, favorite_activity} = CommonAPI.favorite(create_activity.id, another_user)
{:ok, [notification]} = Notification.create_notifications(favorite_activity)
create_activity = Activity.get_by_id(create_activity.id)
@@ -331,4 +331,31 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
test_notifications_rendering([notification], user, [expected])
end
+
+ test "Subscribed status notification" do
+ user = insert(:user)
+ subscriber = insert(:user)
+
+ User.subscribe(subscriber, user)
+
+ {:ok, activity} = CommonAPI.post(user, %{status: "hi"})
+ {:ok, [notification]} = Notification.create_notifications(activity)
+
+ user = User.get_cached_by_id(user.id)
+
+ expected = %{
+ id: to_string(notification.id),
+ pleroma: %{is_seen: false, is_muted: false},
+ type: "status",
+ account:
+ AccountView.render("show.json", %{
+ user: user,
+ for: subscriber
+ }),
+ status: StatusView.render("show.json", %{activity: activity, for: subscriber}),
+ created_at: Utils.to_masto_date(notification.inserted_at)
+ }
+
+ test_notifications_rendering([notification], subscriber, [expected])
+ end
end
diff --git a/test/pleroma/web/mastodon_api/views/poll_view_test.exs b/test/pleroma/web/mastodon_api/views/poll_view_test.exs
index 3aa73c224..6de001421 100644
--- a/test/pleroma/web/mastodon_api/views/poll_view_test.exs
+++ b/test/pleroma/web/mastodon_api/views/poll_view_test.exs
@@ -74,7 +74,7 @@ defmodule Pleroma.Web.MastodonAPI.PollViewTest do
object = Object.normalize(activity, fetch: false)
- {:ok, _votes, object} = CommonAPI.vote(voter, object, [0, 1])
+ {:ok, _votes, object} = CommonAPI.vote(object, voter, [0, 1])
assert match?(
%{
@@ -119,7 +119,7 @@ defmodule Pleroma.Web.MastodonAPI.PollViewTest do
object = Object.normalize(activity, fetch: false)
- {:ok, _, object} = CommonAPI.vote(other_user, object, [1, 2])
+ {:ok, _, object} = CommonAPI.vote(object, other_user, [1, 2])
result = PollView.render("show.json", %{object: object, for: other_user})
diff --git a/test/pleroma/web/mastodon_api/views/status_view_test.exs b/test/pleroma/web/mastodon_api/views/status_view_test.exs
index 8278724d9..0ff43ada4 100644
--- a/test/pleroma/web/mastodon_api/views/status_view_test.exs
+++ b/test/pleroma/web/mastodon_api/views/status_view_test.exs
@@ -201,7 +201,6 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
end
- @tag capture_log: true
test "returns a temporary ap_id based user for activities missing db users" do
user = insert(:user)
@@ -389,7 +388,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
assert status.pleroma.thread_muted == false
- {:ok, activity} = CommonAPI.add_mute(user, activity)
+ {:ok, activity} = CommonAPI.add_mute(activity, user)
status = StatusView.render("show.json", %{activity: activity, for: user})
@@ -467,7 +466,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
# Create a public post quoting the private post
quote_private =
- insert(:note_activity, note: insert(:note, data: %{"quoteUrl" => private_object.data["id"]}))
+ insert(:note_activity,
+ note: insert(:note, data: %{"quoteUrl" => private_object.data["id"]})
+ )
status = StatusView.render("show.json", %{activity: quote_private})
@@ -478,7 +479,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
# After following the user, the quote is rendered
follower = insert(:user)
- CommonAPI.follow(follower, user)
+ CommonAPI.follow(user, follower)
status = StatusView.render("show.json", %{activity: quote_private, for: follower})
assert status.pleroma.quote.id == to_string(private.id)
@@ -591,45 +592,78 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
assert mention.url == recipient.ap_id
end
- test "attachments" do
- object = %{
- "type" => "Image",
- "url" => [
- %{
- "mediaType" => "image/png",
- "href" => "someurl",
- "width" => 200,
- "height" => 100
- }
- ],
- "blurhash" => "UJJ8X[xYW,%Jtq%NNFbXB5j]IVM|9GV=WHRn",
- "uuid" => 6
- }
+ describe "attachments" do
+ test "Complete Mastodon style" do
+ object = %{
+ "type" => "Image",
+ "url" => [
+ %{
+ "mediaType" => "image/png",
+ "href" => "someurl",
+ "width" => 200,
+ "height" => 100
+ }
+ ],
+ "blurhash" => "UJJ8X[xYW,%Jtq%NNFbXB5j]IVM|9GV=WHRn",
+ "uuid" => 6
+ }
- expected = %{
- id: "1638338801",
- type: "image",
- url: "someurl",
- remote_url: "someurl",
- preview_url: "someurl",
- text_url: "someurl",
- description: nil,
- pleroma: %{mime_type: "image/png"},
- meta: %{original: %{width: 200, height: 100, aspect: 2}},
- blurhash: "UJJ8X[xYW,%Jtq%NNFbXB5j]IVM|9GV=WHRn"
- }
+ expected = %{
+ id: "1638338801",
+ type: "image",
+ url: "someurl",
+ remote_url: "someurl",
+ preview_url: "someurl",
+ text_url: "someurl",
+ description: nil,
+ pleroma: %{mime_type: "image/png"},
+ meta: %{original: %{width: 200, height: 100, aspect: 2}},
+ blurhash: "UJJ8X[xYW,%Jtq%NNFbXB5j]IVM|9GV=WHRn"
+ }
- api_spec = Pleroma.Web.ApiSpec.spec()
+ api_spec = Pleroma.Web.ApiSpec.spec()
- assert expected == StatusView.render("attachment.json", %{attachment: object})
- assert_schema(expected, "Attachment", api_spec)
+ assert expected == StatusView.render("attachment.json", %{attachment: object})
+ assert_schema(expected, "Attachment", api_spec)
- # If theres a "id", use that instead of the generated one
- object = Map.put(object, "id", 2)
- result = StatusView.render("attachment.json", %{attachment: object})
+ # If theres a "id", use that instead of the generated one
+ object = Map.put(object, "id", 2)
+ result = StatusView.render("attachment.json", %{attachment: object})
- assert %{id: "2"} = result
- assert_schema(result, "Attachment", api_spec)
+ assert %{id: "2"} = result
+ assert_schema(result, "Attachment", api_spec)
+ end
+
+ test "Honkerific" do
+ object = %{
+ "type" => "Image",
+ "url" => [
+ %{
+ "mediaType" => "image/png",
+ "href" => "someurl"
+ }
+ ],
+ "name" => "fool.jpeg",
+ "summary" => "they have played us for absolute fools."
+ }
+
+ expected = %{
+ blurhash: nil,
+ description: "they have played us for absolute fools.",
+ id: "1638338801",
+ pleroma: %{mime_type: "image/png", name: "fool.jpeg"},
+ preview_url: "someurl",
+ remote_url: "someurl",
+ text_url: "someurl",
+ type: "image",
+ url: "someurl"
+ }
+
+ api_spec = Pleroma.Web.ApiSpec.spec()
+
+ assert expected == StatusView.render("attachment.json", %{attachment: object})
+ assert_schema(expected, "Attachment", api_spec)
+ end
end
test "put the url advertised in the Activity in to the url attribute" do
@@ -904,7 +938,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
status = StatusView.render("show.json", activity: post)
refute status.edited_at
- {:ok, _} = CommonAPI.update(poster, post, %{status: "mew mew"})
+ {:ok, _} = CommonAPI.update(post, poster, %{status: "mew mew"})
edited = Pleroma.Activity.normalize(post)
status = StatusView.render("show.json", activity: edited)
diff --git a/test/pleroma/web/metadata/utils_test.exs b/test/pleroma/web/metadata/utils_test.exs
index 3daf852fb..f986d3fd5 100644
--- a/test/pleroma/web/metadata/utils_test.exs
+++ b/test/pleroma/web/metadata/utils_test.exs
@@ -8,7 +8,7 @@ defmodule Pleroma.Web.Metadata.UtilsTest do
alias Pleroma.Web.Metadata.Utils
describe "scrub_html_and_truncate/1" do
- test "it returns content text without encode HTML if summary is nil" do
+ test "it returns content text without HTML if summary is nil" do
user = insert(:user)
note =
@@ -17,14 +17,14 @@ defmodule Pleroma.Web.Metadata.UtilsTest do
"actor" => user.ap_id,
"id" => "https://pleroma.gov/objects/whatever",
"summary" => nil,
- "content" => "Pleroma's really cool!"
+ "content" => "Pleroma's really cool!<br>"
}
})
assert Utils.scrub_html_and_truncate(note) == "Pleroma's really cool!"
end
- test "it returns context text without encode HTML if summary is empty" do
+ test "it returns content text without HTML if summary is empty" do
user = insert(:user)
note =
@@ -33,14 +33,14 @@ defmodule Pleroma.Web.Metadata.UtilsTest do
"actor" => user.ap_id,
"id" => "https://pleroma.gov/objects/whatever",
"summary" => "",
- "content" => "Pleroma's really cool!"
+ "content" => "Pleroma's really cool!<br>"
}
})
assert Utils.scrub_html_and_truncate(note) == "Pleroma's really cool!"
end
- test "it returns summary text without encode HTML if summary is filled" do
+ test "it returns summary text without HTML if summary is filled" do
user = insert(:user)
note =
@@ -48,7 +48,7 @@ defmodule Pleroma.Web.Metadata.UtilsTest do
data: %{
"actor" => user.ap_id,
"id" => "https://pleroma.gov/objects/whatever",
- "summary" => "Public service announcement on caffeine consumption",
+ "summary" => "Public service announcement on caffeine consumption<br>",
"content" => "cofe"
}
})
@@ -57,6 +57,22 @@ defmodule Pleroma.Web.Metadata.UtilsTest do
"Public service announcement on caffeine consumption"
end
+ test "it returns empty string if summary and content are absent" do
+ user = insert(:user)
+
+ note =
+ insert(:note, %{
+ data: %{
+ "actor" => user.ap_id,
+ "id" => "https://pleroma.gov/objects/whatever",
+ "content" => nil,
+ "summary" => nil
+ }
+ })
+
+ assert Utils.scrub_html_and_truncate(note) == ""
+ end
+
test "it does not return old content after editing" do
user = insert(:user)
@@ -65,7 +81,7 @@ defmodule Pleroma.Web.Metadata.UtilsTest do
object = Pleroma.Object.normalize(activity)
assert Utils.scrub_html_and_truncate(object) == "mew mew #def"
- {:ok, update} = Pleroma.Web.CommonAPI.update(user, activity, %{status: "mew mew #abc"})
+ {:ok, update} = Pleroma.Web.CommonAPI.update(activity, user, %{status: "mew mew #abc"})
update = Pleroma.Activity.normalize(update)
object = Pleroma.Object.normalize(update)
assert Utils.scrub_html_and_truncate(object) == "mew mew #abc"
diff --git a/test/pleroma/web/o_auth/ldap_authorization_test.exs b/test/pleroma/web/o_auth/ldap_authorization_test.exs
index 5ab8236b5..07ce2eed8 100644
--- a/test/pleroma/web/o_auth/ldap_authorization_test.exs
+++ b/test/pleroma/web/o_auth/ldap_authorization_test.exs
@@ -71,7 +71,7 @@ defmodule Pleroma.Web.OAuth.LDAPAuthorizationTest do
equalityMatch: fn _type, _value -> :ok end,
wholeSubtree: fn -> :ok end,
search: fn _connection, _options ->
- {:ok, {:eldap_search_result, [{:eldap_entry, '', []}], []}}
+ {:ok, {:eldap_search_result, [{:eldap_entry, ~c"", []}], []}}
end,
close: fn _connection ->
send(self(), :close_connection)
diff --git a/test/pleroma/web/o_status/o_status_controller_test.exs b/test/pleroma/web/o_status/o_status_controller_test.exs
index 3e8fcd956..5387ec94e 100644
--- a/test/pleroma/web/o_status/o_status_controller_test.exs
+++ b/test/pleroma/web/o_status/o_status_controller_test.exs
@@ -186,7 +186,7 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
user = insert(:user)
- {:ok, like_activity} = CommonAPI.favorite(user, note_activity.id)
+ {:ok, like_activity} = CommonAPI.favorite(note_activity.id, user)
assert like_activity.data["type"] == "Like"
diff --git a/test/pleroma/web/pleroma_api/controllers/account_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/account_controller_test.exs
index 8f000760f..61880e2c0 100644
--- a/test/pleroma/web/pleroma_api/controllers/account_controller_test.exs
+++ b/test/pleroma/web/pleroma_api/controllers/account_controller_test.exs
@@ -78,7 +78,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
user: user
} do
[activity | _] = insert_pair(:note_activity)
- CommonAPI.favorite(user, activity.id)
+ CommonAPI.favorite(activity.id, user)
response =
conn
@@ -95,7 +95,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
user: user
} do
activity = insert(:note_activity)
- CommonAPI.favorite(user, activity.id)
+ CommonAPI.favorite(activity.id, user)
response =
build_conn()
@@ -115,7 +115,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
visibility: "direct"
})
- CommonAPI.favorite(user, direct.id)
+ CommonAPI.favorite(direct.id, user)
for u <- [user, current_user] do
response =
@@ -148,7 +148,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
visibility: "direct"
})
- CommonAPI.favorite(user, direct.id)
+ CommonAPI.favorite(direct.id, user)
response =
conn
@@ -165,7 +165,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
activities = insert_list(10, :note_activity)
Enum.each(activities, fn activity ->
- CommonAPI.favorite(user, activity.id)
+ CommonAPI.favorite(activity.id, user)
end)
third_activity = Enum.at(activities, 2)
@@ -190,7 +190,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
7
|> insert_list(:note_activity)
|> Enum.each(fn activity ->
- CommonAPI.favorite(user, activity.id)
+ CommonAPI.favorite(activity.id, user)
end)
response =
@@ -222,7 +222,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
test "returns 403 error when user has hidden own favorites", %{conn: conn} do
user = insert(:user, hide_favorites: true)
activity = insert(:note_activity)
- CommonAPI.favorite(user, activity.id)
+ CommonAPI.favorite(activity.id, user)
conn = get(conn, "/api/v1/pleroma/accounts/#{user.id}/favourites")
@@ -232,7 +232,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
test "hides favorites for new users by default", %{conn: conn} do
user = insert(:user)
activity = insert(:note_activity)
- CommonAPI.favorite(user, activity.id)
+ CommonAPI.favorite(activity.id, user)
assert user.hide_favorites
conn = get(conn, "/api/v1/pleroma/accounts/#{user.id}/favourites")
@@ -286,8 +286,8 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
%{id: id2} = user2 = insert(:user)
%{id: id3} = user3 = insert(:user)
- CommonAPI.follow(user1, user2)
- CommonAPI.follow(user1, user3)
+ CommonAPI.follow(user2, user1)
+ CommonAPI.follow(user3, user1)
User.endorse(user1, user2)
User.endorse(user1, user3)
@@ -324,9 +324,9 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
user3 = insert(:user)
- CommonAPI.follow(user, user1)
- CommonAPI.follow(user, user2)
- CommonAPI.follow(user, user3)
+ CommonAPI.follow(user1, user)
+ CommonAPI.follow(user2, user)
+ CommonAPI.follow(user3, user)
[%{"id" => ^id1}] =
conn
@@ -350,8 +350,8 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
show_birthday: true
})
- CommonAPI.follow(user, user1)
- CommonAPI.follow(user, user2)
+ CommonAPI.follow(user1, user)
+ CommonAPI.follow(user2, user)
[%{"id" => ^id2}] =
conn
diff --git a/test/pleroma/web/pleroma_api/controllers/emoji_pack_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/emoji_pack_controller_test.exs
index 92334487c..10dcf0e62 100644
--- a/test/pleroma/web/pleroma_api/controllers/emoji_pack_controller_test.exs
+++ b/test/pleroma/web/pleroma_api/controllers/emoji_pack_controller_test.exs
@@ -159,8 +159,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
{:ok, arch} = :zip.unzip(resp, [:memory])
- assert Enum.find(arch, fn {n, _} -> n == 'pack.json' end)
- assert Enum.find(arch, fn {n, _} -> n == 'blank.png' end)
+ assert Enum.find(arch, fn {n, _} -> n == ~c"pack.json" end)
+ assert Enum.find(arch, fn {n, _} -> n == ~c"blank.png" end)
end
test "non existing pack", %{conn: conn} do
@@ -454,7 +454,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
method: :get,
url: "https://nonshared-pack"
} ->
- {:ok, {'empty.zip', empty_arch}} = :zip.zip('empty.zip', [], [:memory])
+ {:ok, {~c"empty.zip", empty_arch}} = :zip.zip(~c"empty.zip", [], [:memory])
text(empty_arch)
end)
diff --git a/test/pleroma/web/pleroma_api/controllers/notification_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/notification_controller_test.exs
index b8c7964f9..036cbf176 100644
--- a/test/pleroma/web/pleroma_api/controllers/notification_controller_test.exs
+++ b/test/pleroma/web/pleroma_api/controllers/notification_controller_test.exs
@@ -21,13 +21,11 @@ defmodule Pleroma.Web.PleromaAPI.NotificationControllerTest do
{:ok, [notification1]} = Notification.create_notifications(activity1)
{:ok, [notification2]} = Notification.create_notifications(activity2)
- response =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/pleroma/notifications/read", %{id: notification1.id})
- |> json_response_and_validate_schema(:ok)
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/pleroma/notifications/read", %{id: notification1.id})
+ |> json_response_and_validate_schema(:ok)
- assert %{"pleroma" => %{"is_seen" => true}} = response
assert Repo.get(Notification, notification1.id).seen
refute Repo.get(Notification, notification2.id).seen
end
@@ -40,14 +38,17 @@ defmodule Pleroma.Web.PleromaAPI.NotificationControllerTest do
[notification3, notification2, notification1] = Notification.for_user(user1, %{limit: 3})
- [response1, response2] =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/pleroma/notifications/read", %{max_id: notification2.id})
- |> json_response_and_validate_schema(:ok)
+ refute Repo.get(Notification, notification1.id).seen
+ refute Repo.get(Notification, notification2.id).seen
+ refute Repo.get(Notification, notification3.id).seen
+
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/pleroma/notifications/read", %{max_id: notification2.id})
+ |> json_response_and_validate_schema(:ok)
+
+ [notification3, notification2, notification1] = Notification.for_user(user1, %{limit: 3})
- assert %{"pleroma" => %{"is_seen" => true}} = response1
- assert %{"pleroma" => %{"is_seen" => true}} = response2
assert Repo.get(Notification, notification1.id).seen
assert Repo.get(Notification, notification2.id).seen
refute Repo.get(Notification, notification3.id).seen
diff --git a/test/pleroma/web/pleroma_api/views/chat_message_reference_view_test.exs b/test/pleroma/web/pleroma_api/views/chat_message_reference_view_test.exs
index f17add774..c78c03aba 100644
--- a/test/pleroma/web/pleroma_api/views/chat_message_reference_view_test.exs
+++ b/test/pleroma/web/pleroma_api/views/chat_message_reference_view_test.exs
@@ -9,6 +9,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatMessageReferenceViewTest do
alias Pleroma.Chat
alias Pleroma.Chat.MessageReference
alias Pleroma.Object
+ alias Pleroma.Tests.ObanHelpers
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.CommonAPI
@@ -70,6 +71,8 @@ defmodule Pleroma.Web.PleromaAPI.ChatMessageReferenceViewTest do
media_id: upload.id
)
+ ObanHelpers.perform_all()
+
object = Object.normalize(activity, fetch: false)
cm_ref = MessageReference.for_chat_and_object(chat, object)
diff --git a/test/pleroma/web/plugs/http_security_plug_test.exs b/test/pleroma/web/plugs/http_security_plug_test.exs
index c79170382..11a351a41 100644
--- a/test/pleroma/web/plugs/http_security_plug_test.exs
+++ b/test/pleroma/web/plugs/http_security_plug_test.exs
@@ -3,14 +3,52 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do
- use Pleroma.Web.ConnCase
+ use Pleroma.Web.ConnCase, async: true
alias Plug.Conn
+ import Mox
+
+ setup do
+ base_config = Pleroma.Config.get([:http_security])
+ %{base_config: base_config}
+ end
+
+ defp mock_config(config, additional \\ %{}) do
+ Pleroma.StaticStubbedConfigMock
+ |> stub(:get, fn
+ [:http_security, key] -> config[key]
+ key -> additional[key]
+ end)
+ end
+
describe "http security enabled" do
- setup do: clear_config([:http_security, :enabled], true)
+ setup %{base_config: base_config} do
+ %{base_config: Keyword.put(base_config, :enabled, true)}
+ end
+
+ test "it does not contain unsafe-eval", %{conn: conn, base_config: base_config} do
+ mock_config(base_config)
+
+ conn = get(conn, "/api/v1/instance")
+ [header] = Conn.get_resp_header(conn, "content-security-policy")
+ refute header =~ ~r/unsafe-eval/
+ end
+
+ test "with allow_unsafe_eval set, it does contain it", %{conn: conn, base_config: base_config} do
+ base_config =
+ base_config
+ |> Keyword.put(:allow_unsafe_eval, true)
+
+ mock_config(base_config)
+
+ conn = get(conn, "/api/v1/instance")
+ [header] = Conn.get_resp_header(conn, "content-security-policy")
+ assert header =~ ~r/unsafe-eval/
+ end
- test "it sends CSP headers when enabled", %{conn: conn} do
+ test "it sends CSP headers when enabled", %{conn: conn, base_config: base_config} do
+ mock_config(base_config)
conn = get(conn, "/api/v1/instance")
refute Conn.get_resp_header(conn, "x-xss-protection") == []
@@ -22,8 +60,10 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do
refute Conn.get_resp_header(conn, "content-security-policy") == []
end
- test "it sends STS headers when enabled", %{conn: conn} do
- clear_config([:http_security, :sts], true)
+ test "it sends STS headers when enabled", %{conn: conn, base_config: base_config} do
+ base_config
+ |> Keyword.put(:sts, true)
+ |> mock_config()
conn = get(conn, "/api/v1/instance")
@@ -31,8 +71,10 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do
refute Conn.get_resp_header(conn, "expect-ct") == []
end
- test "it does not send STS headers when disabled", %{conn: conn} do
- clear_config([:http_security, :sts], false)
+ test "it does not send STS headers when disabled", %{conn: conn, base_config: base_config} do
+ base_config
+ |> Keyword.put(:sts, false)
+ |> mock_config()
conn = get(conn, "/api/v1/instance")
@@ -40,19 +82,30 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do
assert Conn.get_resp_header(conn, "expect-ct") == []
end
- test "referrer-policy header reflects configured value", %{conn: conn} do
- resp = get(conn, "/api/v1/instance")
+ test "referrer-policy header reflects configured value", %{
+ conn: conn,
+ base_config: base_config
+ } do
+ mock_config(base_config)
+ resp = get(conn, "/api/v1/instance")
assert Conn.get_resp_header(resp, "referrer-policy") == ["same-origin"]
- clear_config([:http_security, :referrer_policy], "no-referrer")
+ base_config
+ |> Keyword.put(:referrer_policy, "no-referrer")
+ |> mock_config
resp = get(conn, "/api/v1/instance")
assert Conn.get_resp_header(resp, "referrer-policy") == ["no-referrer"]
end
- test "it sends `report-to` & `report-uri` CSP response headers", %{conn: conn} do
+ test "it sends `report-to` & `report-uri` CSP response headers", %{
+ conn: conn,
+ base_config: base_config
+ } do
+ mock_config(base_config)
+
conn = get(conn, "/api/v1/instance")
[csp] = Conn.get_resp_header(conn, "content-security-policy")
@@ -65,7 +118,11 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do
"{\"endpoints\":[{\"url\":\"https://endpoint.com\"}],\"group\":\"csp-endpoint\",\"max-age\":10886400}"
end
- test "default values for img-src and media-src with disabled media proxy", %{conn: conn} do
+ test "default values for img-src and media-src with disabled media proxy", %{
+ conn: conn,
+ base_config: base_config
+ } do
+ mock_config(base_config)
conn = get(conn, "/api/v1/instance")
[csp] = Conn.get_resp_header(conn, "content-security-policy")
@@ -73,60 +130,129 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do
assert csp =~ "img-src 'self' data: blob: https:;"
end
- test "it sets the Service-Worker-Allowed header", %{conn: conn} do
- clear_config([:http_security, :enabled], true)
- clear_config([:frontends, :primary], %{"name" => "fedi-fe", "ref" => "develop"})
-
- clear_config([:frontends, :available], %{
- "fedi-fe" => %{
- "name" => "fedi-fe",
- "custom-http-headers" => [{"service-worker-allowed", "/"}]
- }
- })
-
+ test "it sets the Service-Worker-Allowed header", %{conn: conn, base_config: base_config} do
+ base_config
+ |> Keyword.put(:enabled, true)
+
+ additional_config =
+ %{}
+ |> Map.put([:frontends, :primary], %{"name" => "fedi-fe", "ref" => "develop"})
+ |> Map.put(
+ [:frontends, :available],
+ %{
+ "fedi-fe" => %{
+ "name" => "fedi-fe",
+ "custom-http-headers" => [{"service-worker-allowed", "/"}]
+ }
+ }
+ )
+
+ mock_config(base_config, additional_config)
conn = get(conn, "/api/v1/instance")
assert Conn.get_resp_header(conn, "service-worker-allowed") == ["/"]
end
end
describe "img-src and media-src" do
- setup do
- clear_config([:http_security, :enabled], true)
- clear_config([:media_proxy, :enabled], true)
- clear_config([:media_proxy, :proxy_opts, :redirect_on_failure], false)
+ setup %{base_config: base_config} do
+ base_config =
+ base_config
+ |> Keyword.put(:enabled, true)
+
+ additional_config =
+ %{}
+ |> Map.put([:media_proxy, :enabled], true)
+ |> Map.put([:media_proxy, :proxy_opts, :redirect_on_failure], false)
+ |> Map.put([:media_proxy, :whitelist], [])
+
+ %{base_config: base_config, additional_config: additional_config}
end
- test "media_proxy with base_url", %{conn: conn} do
+ test "media_proxy with base_url", %{
+ conn: conn,
+ base_config: base_config,
+ additional_config: additional_config
+ } do
url = "https://example.com"
- clear_config([:media_proxy, :base_url], url)
+
+ additional_config =
+ additional_config
+ |> Map.put([:media_proxy, :base_url], url)
+
+ mock_config(base_config, additional_config)
+
assert_media_img_src(conn, url)
end
- test "upload with base url", %{conn: conn} do
+ test "upload with base url", %{
+ conn: conn,
+ base_config: base_config,
+ additional_config: additional_config
+ } do
url = "https://example2.com"
- clear_config([Pleroma.Upload, :base_url], url)
+
+ additional_config =
+ additional_config
+ |> Map.put([Pleroma.Upload, :base_url], url)
+
+ mock_config(base_config, additional_config)
+
assert_media_img_src(conn, url)
end
- test "with S3 public endpoint", %{conn: conn} do
+ test "with S3 public endpoint", %{
+ conn: conn,
+ base_config: base_config,
+ additional_config: additional_config
+ } do
url = "https://example3.com"
- clear_config([Pleroma.Uploaders.S3, :public_endpoint], url)
+
+ additional_config =
+ additional_config
+ |> Map.put([Pleroma.Uploaders.S3, :public_endpoint], url)
+
+ mock_config(base_config, additional_config)
assert_media_img_src(conn, url)
end
- test "with captcha endpoint", %{conn: conn} do
- clear_config([Pleroma.Captcha.Mock, :endpoint], "https://captcha.com")
+ test "with captcha endpoint", %{
+ conn: conn,
+ base_config: base_config,
+ additional_config: additional_config
+ } do
+ additional_config =
+ additional_config
+ |> Map.put([Pleroma.Captcha.Mock, :endpoint], "https://captcha.com")
+ |> Map.put([Pleroma.Captcha, :method], Pleroma.Captcha.Mock)
+
+ mock_config(base_config, additional_config)
assert_media_img_src(conn, "https://captcha.com")
end
- test "with media_proxy whitelist", %{conn: conn} do
- clear_config([:media_proxy, :whitelist], ["https://example6.com", "https://example7.com"])
+ test "with media_proxy whitelist", %{
+ conn: conn,
+ base_config: base_config,
+ additional_config: additional_config
+ } do
+ additional_config =
+ additional_config
+ |> Map.put([:media_proxy, :whitelist], ["https://example6.com", "https://example7.com"])
+
+ mock_config(base_config, additional_config)
assert_media_img_src(conn, "https://example7.com https://example6.com")
end
# TODO: delete after removing support bare domains for media proxy whitelist
- test "with media_proxy bare domains whitelist (deprecated)", %{conn: conn} do
- clear_config([:media_proxy, :whitelist], ["example4.com", "example5.com"])
+ test "with media_proxy bare domains whitelist (deprecated)", %{
+ conn: conn,
+ base_config: base_config,
+ additional_config: additional_config
+ } do
+ additional_config =
+ additional_config
+ |> Map.put([:media_proxy, :whitelist], ["example4.com", "example5.com"])
+
+ mock_config(base_config, additional_config)
assert_media_img_src(conn, "example5.com example4.com")
end
end
@@ -138,8 +264,10 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do
assert csp =~ "img-src 'self' data: blob: #{url};"
end
- test "it does not send CSP headers when disabled", %{conn: conn} do
- clear_config([:http_security, :enabled], false)
+ test "it does not send CSP headers when disabled", %{conn: conn, base_config: base_config} do
+ base_config
+ |> Keyword.put(:enabled, false)
+ |> mock_config
conn = get(conn, "/api/v1/instance")
diff --git a/test/pleroma/web/plugs/http_signature_plug_test.exs b/test/pleroma/web/plugs/http_signature_plug_test.exs
index 2d8fba3cd..9d07270bb 100644
--- a/test/pleroma/web/plugs/http_signature_plug_test.exs
+++ b/test/pleroma/web/plugs/http_signature_plug_test.exs
@@ -3,77 +3,89 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.HTTPSignaturePlugTest do
- use Pleroma.Web.ConnCase
+ use Pleroma.Web.ConnCase, async: true
+
+ alias Pleroma.StaticStubbedConfigMock, as: ConfigMock
+ alias Pleroma.StubbedHTTPSignaturesMock, as: HTTPSignaturesMock
alias Pleroma.Web.Plugs.HTTPSignaturePlug
- import Plug.Conn
+ import Mox
import Phoenix.Controller, only: [put_format: 2]
- import Mock
+ import Plug.Conn
- test "it call HTTPSignatures to check validity if the actor sighed it" do
+ test "it calls HTTPSignatures to check validity if the actor signed it" do
params = %{"actor" => "http://mastodon.example.org/users/admin"}
conn = build_conn(:get, "/doesntmattter", params)
- with_mock HTTPSignatures, validate_conn: fn _ -> true end do
- conn =
- conn
- |> put_req_header(
- "signature",
- "keyId=\"http://mastodon.example.org/users/admin#main-key"
- )
- |> put_format("activity+json")
- |> HTTPSignaturePlug.call(%{})
+ HTTPSignaturesMock
+ |> expect(:validate_conn, fn _ -> true end)
- assert conn.assigns.valid_signature == true
- assert conn.halted == false
- assert called(HTTPSignatures.validate_conn(:_))
- end
+ conn =
+ conn
+ |> put_req_header(
+ "signature",
+ "keyId=\"http://mastodon.example.org/users/admin#main-key"
+ )
+ |> put_format("activity+json")
+ |> HTTPSignaturePlug.call(%{})
+
+ assert conn.assigns.valid_signature == true
+ assert conn.halted == false
end
describe "requires a signature when `authorized_fetch_mode` is enabled" do
setup do
- clear_config([:activitypub, :authorized_fetch_mode], true)
-
params = %{"actor" => "http://mastodon.example.org/users/admin"}
conn = build_conn(:get, "/doesntmattter", params) |> put_format("activity+json")
[conn: conn]
end
- test "when signature header is present", %{conn: conn} do
- with_mock HTTPSignatures, validate_conn: fn _ -> false end do
- conn =
- conn
- |> put_req_header(
- "signature",
- "keyId=\"http://mastodon.example.org/users/admin#main-key"
- )
- |> HTTPSignaturePlug.call(%{})
-
- assert conn.assigns.valid_signature == false
- assert conn.halted == true
- assert conn.status == 401
- assert conn.state == :sent
- assert conn.resp_body == "Request not signed"
- assert called(HTTPSignatures.validate_conn(:_))
- end
-
- with_mock HTTPSignatures, validate_conn: fn _ -> true end do
- conn =
- conn
- |> put_req_header(
- "signature",
- "keyId=\"http://mastodon.example.org/users/admin#main-key"
- )
- |> HTTPSignaturePlug.call(%{})
-
- assert conn.assigns.valid_signature == true
- assert conn.halted == false
- assert called(HTTPSignatures.validate_conn(:_))
- end
+ test "when signature header is present", %{conn: orig_conn} do
+ ConfigMock
+ |> expect(:get, fn [:activitypub, :authorized_fetch_mode], false -> true end)
+ |> expect(:get, fn [:activitypub, :authorized_fetch_mode_exceptions], [] -> [] end)
+
+ HTTPSignaturesMock
+ |> expect(:validate_conn, 2, fn _ -> false end)
+
+ conn =
+ orig_conn
+ |> put_req_header(
+ "signature",
+ "keyId=\"http://mastodon.example.org/users/admin#main-key"
+ )
+ |> HTTPSignaturePlug.call(%{})
+
+ assert conn.assigns.valid_signature == false
+ assert conn.halted == true
+ assert conn.status == 401
+ assert conn.state == :sent
+ assert conn.resp_body == "Request not signed"
+
+ ConfigMock
+ |> expect(:get, fn [:activitypub, :authorized_fetch_mode], false -> true end)
+
+ HTTPSignaturesMock
+ |> expect(:validate_conn, fn _ -> true end)
+
+ conn =
+ orig_conn
+ |> put_req_header(
+ "signature",
+ "keyId=\"http://mastodon.example.org/users/admin#main-key"
+ )
+ |> HTTPSignaturePlug.call(%{})
+
+ assert conn.assigns.valid_signature == true
+ assert conn.halted == false
end
test "halts the connection when `signature` header is not present", %{conn: conn} do
+ ConfigMock
+ |> expect(:get, fn [:activitypub, :authorized_fetch_mode], false -> true end)
+ |> expect(:get, fn [:activitypub, :authorized_fetch_mode_exceptions], [] -> [] end)
+
conn = HTTPSignaturePlug.call(conn, %{})
assert conn.assigns[:valid_signature] == nil
assert conn.halted == true
@@ -81,5 +93,73 @@ defmodule Pleroma.Web.Plugs.HTTPSignaturePlugTest do
assert conn.state == :sent
assert conn.resp_body == "Request not signed"
end
+
+ test "exempts specific IPs from `authorized_fetch_mode_exceptions`", %{conn: conn} do
+ ConfigMock
+ |> expect(:get, fn [:activitypub, :authorized_fetch_mode], false -> true end)
+ |> expect(:get, fn [:activitypub, :authorized_fetch_mode_exceptions], [] ->
+ ["192.168.0.0/24"]
+ end)
+ |> expect(:get, fn [:activitypub, :authorized_fetch_mode], false -> true end)
+
+ HTTPSignaturesMock
+ |> expect(:validate_conn, 2, fn _ -> false end)
+
+ conn =
+ conn
+ |> Map.put(:remote_ip, {192, 168, 0, 1})
+ |> put_req_header(
+ "signature",
+ "keyId=\"http://mastodon.example.org/users/admin#main-key"
+ )
+ |> HTTPSignaturePlug.call(%{})
+
+ assert conn.remote_ip == {192, 168, 0, 1}
+ assert conn.halted == false
+ end
+ end
+
+ test "rejects requests from `rejected_instances` when `authorized_fetch_mode` is enabled" do
+ ConfigMock
+ |> expect(:get, fn [:activitypub, :authorized_fetch_mode], false -> true end)
+ |> expect(:get, fn [:instance, :rejected_instances] ->
+ [{"mastodon.example.org", "no reason"}]
+ end)
+
+ HTTPSignaturesMock
+ |> expect(:validate_conn, fn _ -> true end)
+
+ conn =
+ build_conn(:get, "/doesntmattter", %{"actor" => "http://mastodon.example.org/users/admin"})
+ |> put_req_header(
+ "signature",
+ "keyId=\"http://mastodon.example.org/users/admin#main-key"
+ )
+ |> put_format("activity+json")
+ |> HTTPSignaturePlug.call(%{})
+
+ assert conn.assigns.valid_signature == true
+ assert conn.halted == true
+
+ ConfigMock
+ |> expect(:get, fn [:activitypub, :authorized_fetch_mode], false -> true end)
+ |> expect(:get, fn [:instance, :rejected_instances] ->
+ [{"mastodon.example.org", "no reason"}]
+ end)
+
+ HTTPSignaturesMock
+ |> expect(:validate_conn, fn _ -> true end)
+
+ conn =
+ build_conn(:get, "/doesntmattter", %{"actor" => "http://allowed.example.org/users/admin"})
+ |> put_req_header(
+ "signature",
+ "keyId=\"http://allowed.example.org/users/admin#main-key"
+ )
+ |> put_format("activity+json")
+ |> HTTPSignaturePlug.call(%{})
+
+ assert conn.assigns.valid_signature == true
+ assert conn.halted == false
end
end
diff --git a/test/pleroma/web/push/impl_test.exs b/test/pleroma/web/push/impl_test.exs
index 3ceea3d71..ffc38dc80 100644
--- a/test/pleroma/web/push/impl_test.exs
+++ b/test/pleroma/web/push/impl_test.exs
@@ -5,6 +5,7 @@
defmodule Pleroma.Web.Push.ImplTest do
use Pleroma.DataCase, async: true
+ import ExUnit.CaptureLog
import Mox
import Pleroma.Factory
@@ -32,17 +33,6 @@ defmodule Pleroma.Web.Push.ImplTest do
:ok
end
- @sub %{
- endpoint: "https://example.com/example/1234",
- keys: %{
- auth: "8eDyX_uCN0XRhSbY5hs7Hg==",
- p256dh:
- "BCIWgsnyXDv1VkhqL2P7YRBvdeuDnlwAPT2guNhdIoW3IP7GmHh1SMKPLxRf7x8vJy6ZFK3ol2ohgn_-0yP7QQA="
- }
- }
- @api_key "BASgACIHpN1GYgzSRp"
- @message "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini..."
-
test "performs sending notifications" do
user = insert(:user)
user2 = insert(:user)
@@ -68,39 +58,65 @@ defmodule Pleroma.Web.Push.ImplTest do
type: "mention"
)
- assert Impl.perform(notif) == {:ok, [:ok, :ok]}
- end
-
- @tag capture_log: true
- test "returns error if notif does not match " do
- assert Impl.perform(%{}) == {:error, :unknown_type}
+ Impl.build(notif)
+ |> Enum.each(fn push -> assert match?(:ok, Impl.deliver(push)) end)
end
- test "successful message sending" do
- assert Impl.push_message(@message, @sub, @api_key, %Subscription{}) == :ok
+ test "returns error if notification activity type does not match" do
+ assert capture_log(fn ->
+ assert Impl.build(%{}) == []
+ end) =~ "WebPush: unknown activity type"
end
- @tag capture_log: true
test "fail message sending" do
- assert Impl.push_message(
- @message,
- Map.merge(@sub, %{endpoint: "https://example.com/example/bad"}),
- @api_key,
- %Subscription{}
- ) == :error
+ user = insert(:user)
+
+ insert(:push_subscription,
+ user: user,
+ endpoint: "https://example.com/example/bad",
+ data: %{alerts: %{"follow" => true}}
+ )
+
+ other_user = insert(:user)
+ {:ok, _, _, activity} = CommonAPI.follow(other_user, user)
+
+ notif =
+ insert(:notification,
+ user: user,
+ activity: activity,
+ type: "follow"
+ )
+
+ [push] = Impl.build(notif)
+
+ assert Impl.deliver(push) == :error
end
test "delete subscription if result send message between 400..500" do
- subscription = insert(:push_subscription)
+ user = insert(:user)
- assert Impl.push_message(
- @message,
- Map.merge(@sub, %{endpoint: "https://example.com/example/not_found"}),
- @api_key,
- subscription
- ) == :ok
+ bad_subscription =
+ insert(:push_subscription,
+ user: user,
+ endpoint: "https://example.com/example/not_found",
+ data: %{alerts: %{"follow" => true}}
+ )
- refute Pleroma.Repo.get(Subscription, subscription.id)
+ other_user = insert(:user)
+ {:ok, _, _, activity} = CommonAPI.follow(other_user, user)
+
+ notif =
+ insert(:notification,
+ user: user,
+ activity: activity,
+ type: "follow"
+ )
+
+ [push] = Impl.build(notif)
+
+ assert Impl.deliver(push) == :ok
+
+ refute Pleroma.Repo.get(Subscription, bad_subscription.id)
end
test "deletes subscription when token has been deleted" do
@@ -129,7 +145,7 @@ defmodule Pleroma.Web.Push.ImplTest do
user,
object
) ==
- "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini..."
+ "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis finibus turpis."
assert Impl.format_title(%{activity: activity, type: "mention"}) ==
"New Mention"
@@ -138,7 +154,7 @@ defmodule Pleroma.Web.Push.ImplTest do
test "renders title and body for follow activity" do
user = insert(:user, nickname: "Bob")
other_user = insert(:user)
- {:ok, _, _, activity} = CommonAPI.follow(user, other_user)
+ {:ok, _, _, activity} = CommonAPI.follow(other_user, user)
object = Object.normalize(activity, fetch: false)
assert Impl.format_body(%{activity: activity, type: "follow"}, user, object) ==
@@ -161,7 +177,7 @@ defmodule Pleroma.Web.Push.ImplTest do
object = Object.normalize(activity, fetch: false)
assert Impl.format_body(%{activity: announce_activity}, user, object) ==
- "@#{user.nickname} repeated: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini..."
+ "@#{user.nickname} repeated: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis finibus turpis."
assert Impl.format_title(%{activity: announce_activity, type: "reblog"}) ==
"New Repeat"
@@ -176,7 +192,7 @@ defmodule Pleroma.Web.Push.ImplTest do
"<span>Lorem ipsum dolor sit amet</span>, consectetur :firefox: adipiscing elit. Fusce sagittis finibus turpis."
})
- {:ok, activity} = CommonAPI.favorite(user, activity.id)
+ {:ok, activity} = CommonAPI.favorite(activity.id, user)
object = Object.normalize(activity, fetch: false)
assert Impl.format_body(%{activity: activity, type: "favourite"}, user, object) ==
@@ -209,7 +225,7 @@ defmodule Pleroma.Web.Push.ImplTest do
{:ok, activity} = CommonAPI.post(user, %{status: "lorem ipsum"})
- {:ok, activity} = CommonAPI.update(user, activity, %{status: "edited status"})
+ {:ok, activity} = CommonAPI.update(activity, user, %{status: "edited status"})
object = Object.normalize(activity, fetch: false)
assert Impl.format_body(%{activity: activity, type: "update"}, user, object) ==
@@ -232,6 +248,29 @@ defmodule Pleroma.Web.Push.ImplTest do
"New Direct Message"
end
+ test "renders poll notification" do
+ user = insert(:user)
+ question = insert(:question, user: user)
+ activity = insert(:question_activity, question: question)
+
+ {:ok, [notification]} = Notification.create_poll_notifications(activity)
+
+ expected_title = "Poll Results"
+
+ expected_body =
+ """
+ Which flavor of ice cream do you prefer?
+
+ ○ chocolate
+ ○ vanilla
+ """
+ |> String.trim_trailing("\n")
+
+ content = Impl.build_content(notification, user, question)
+
+ assert match?(%{title: ^expected_title, body: ^expected_body}, content)
+ end
+
describe "build_content/3" do
test "builds content for chat messages" do
user = insert(:user)
@@ -312,7 +351,7 @@ defmodule Pleroma.Web.Push.ImplTest do
body: "New Mention"
}
- {:ok, activity} = CommonAPI.favorite(user, activity.id)
+ {:ok, activity} = CommonAPI.favorite(activity.id, user)
notif = insert(:notification, user: user2, activity: activity, type: "favourite")
@@ -328,7 +367,10 @@ defmodule Pleroma.Web.Push.ImplTest do
user = insert(:user, nickname: "Bob")
user2 =
- insert(:user, nickname: "Rob", notification_settings: %{hide_notification_contents: false})
+ insert(:user,
+ nickname: "Rob",
+ notification_settings: %{hide_notification_contents: false}
+ )
{:ok, activity} =
CommonAPI.post(user, %{
@@ -344,7 +386,7 @@ defmodule Pleroma.Web.Push.ImplTest do
assert Impl.build_content(notif, actor, object) == %{
body:
- "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini...",
+ "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis finibus turpis.",
title: "New Direct Message"
}
@@ -362,11 +404,11 @@ defmodule Pleroma.Web.Push.ImplTest do
assert Impl.build_content(notif, actor, object) == %{
body:
- "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini...",
+ "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis finibus turpis.",
title: "New Mention"
}
- {:ok, activity} = CommonAPI.favorite(user, activity.id)
+ {:ok, activity} = CommonAPI.favorite(activity.id, user)
notif = insert(:notification, user: user2, activity: activity, type: "favourite")
@@ -379,4 +421,23 @@ defmodule Pleroma.Web.Push.ImplTest do
}
end
end
+
+ test "build/1 notification payload body starts with nickname of actor the notification originated from" do
+ user = insert(:user, nickname: "Bob")
+ user2 = insert(:user, nickname: "Tom")
+ insert(:push_subscription, user: user2, data: %{alerts: %{"mention" => true}})
+
+ {:ok, activity} =
+ CommonAPI.post(user, %{
+ status: "@Tom Hey are you okay?"
+ })
+
+ {:ok, [notification]} = Notification.create_notifications(activity)
+
+ [push] = Impl.build(notification)
+
+ {:ok, payload} = Jason.decode(push.payload)
+
+ assert String.starts_with?(payload["body"], "@Bob:")
+ end
end
diff --git a/test/pleroma/web/rich_media/backfill_test.exs b/test/pleroma/web/rich_media/backfill_test.exs
new file mode 100644
index 000000000..6d221fcf5
--- /dev/null
+++ b/test/pleroma/web/rich_media/backfill_test.exs
@@ -0,0 +1,26 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.RichMedia.BackfillTest do
+ use Pleroma.DataCase
+
+ alias Pleroma.Web.RichMedia.Backfill
+ alias Pleroma.Web.RichMedia.Card
+
+ import Mox
+
+ setup_all do: clear_config([:rich_media, :enabled], true)
+
+ test "sets a negative cache entry for an error" do
+ url = "https://bad.example.com/"
+ url_hash = Card.url_to_hash(url)
+
+ Tesla.Mock.mock(fn %{url: ^url} -> :error end)
+
+ Pleroma.CachexMock
+ |> expect(:put, fn :rich_media_cache, ^url_hash, :error, ttl: _ -> {:ok, true} end)
+
+ Backfill.run(%{"url" => url})
+ end
+end
diff --git a/test/pleroma/web/rich_media/card_test.exs b/test/pleroma/web/rich_media/card_test.exs
index 516ac9951..387defc8c 100644
--- a/test/pleroma/web/rich_media/card_test.exs
+++ b/test/pleroma/web/rich_media/card_test.exs
@@ -3,11 +3,14 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.RichMedia.CardTest do
+ use Oban.Testing, repo: Pleroma.Repo
use Pleroma.DataCase, async: true
+ alias Pleroma.Tests.ObanHelpers
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.RichMedia.Card
+ alias Pleroma.Workers.RichMediaWorker
import Mox
import Pleroma.Factory
@@ -36,6 +39,16 @@ defmodule Pleroma.Web.RichMedia.CardTest do
content_type: "text/markdown"
})
+ Pleroma.Web.ActivityPub.ActivityPubMock
+ |> expect(:stream_out, fn ^activity -> nil end)
+
+ assert_enqueued(
+ worker: RichMediaWorker,
+ args: %{"url" => url, "activity_id" => activity.id}
+ )
+
+ ObanHelpers.perform_all()
+
assert %Card{url_hash: ^url_hash, fields: _} = Card.get_by_activity(activity)
end
@@ -50,18 +63,20 @@ defmodule Pleroma.Web.RichMedia.CardTest do
# Force a backfill
Card.get_by_activity(activity)
+ ObanHelpers.perform_all()
assert match?(
%Card{url_hash: ^original_url_hash, fields: _},
Card.get_by_activity(activity)
)
- {:ok, _} = CommonAPI.update(user, activity, %{status: "I like this site #{updated_url}"})
+ {:ok, _} = CommonAPI.update(activity, user, %{status: "I like this site #{updated_url}"})
activity = Pleroma.Activity.get_by_id(activity.id)
# Force a backfill
Card.get_by_activity(activity)
+ ObanHelpers.perform_all()
assert match?(
%Card{url_hash: ^updated_url_hash, fields: _},
diff --git a/test/pleroma/web/rich_media/parser/ttl/aws_signed_url_test.exs b/test/pleroma/web/rich_media/parser/ttl/aws_signed_url_test.exs
index cd8be8675..e02dd437a 100644
--- a/test/pleroma/web/rich_media/parser/ttl/aws_signed_url_test.exs
+++ b/test/pleroma/web/rich_media/parser/ttl/aws_signed_url_test.exs
@@ -4,12 +4,14 @@
defmodule Pleroma.Web.RichMedia.Parser.TTL.AwsSignedUrlTest do
use Pleroma.DataCase, async: false
- use Oban.Testing, repo: Pleroma.Repo
+ use Oban.Testing, repo: Pleroma.Repo, testing: :inline
import Mox
+ alias Pleroma.Tests.ObanHelpers
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
alias Pleroma.Web.RichMedia.Card
+ alias Pleroma.Web.RichMedia.Parser.TTL.AwsSignedUrl
setup do
ConfigMock
@@ -73,15 +75,31 @@ defmodule Pleroma.Web.RichMedia.Parser.TTL.AwsSignedUrlTest do
Card.get_or_backfill_by_url(url)
- assert_enqueued(worker: Pleroma.Workers.RichMediaExpirationWorker, args: %{"url" => url})
+ # Find the backfill job
+ expected_job =
+ [
+ worker: "Pleroma.Workers.RichMediaWorker",
+ args: %{"op" => "backfill", "url" => url}
+ ]
- [%Oban.Job{scheduled_at: scheduled_at}] = all_enqueued()
+ assert_enqueued(expected_job)
+
+ # Run it manually
+ ObanHelpers.perform_all()
+
+ [%Oban.Job{scheduled_at: scheduled_at} | _] = all_enqueued()
timestamp_dt = Timex.parse!(timestamp, "{ISO:Basic:Z}")
assert DateTime.diff(scheduled_at, timestamp_dt) == valid_till
end
+ test "AWS URL for an image without expiration works" do
+ og_data = %{"image" => "https://amazonaws.com/image.png"}
+
+ assert is_nil(AwsSignedUrl.ttl(og_data, ""))
+ end
+
defp construct_s3_url(timestamp, valid_till) do
"https://pleroma.s3.ap-southeast-1.amazonaws.com/sachin%20%281%29%20_a%20-%25%2Aasdasd%20BNN%20bnnn%20.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIBLWWK6RGDQXDLJQ%2F20190716%2Fap-southeast-1%2Fs3%2Faws4_request&X-Amz-Date=#{timestamp}&X-Amz-Expires=#{valid_till}&X-Amz-Signature=04ffd6b98634f4b1bbabc62e0fac4879093cd54a6eed24fe8eb38e8369526bbf&X-Amz-SignedHeaders=host"
end
diff --git a/test/pleroma/web/rich_media/parser/ttl/opengraph_test.exs b/test/pleroma/web/rich_media/parser/ttl/opengraph_test.exs
index 770968d47..6805e786d 100644
--- a/test/pleroma/web/rich_media/parser/ttl/opengraph_test.exs
+++ b/test/pleroma/web/rich_media/parser/ttl/opengraph_test.exs
@@ -8,6 +8,7 @@ defmodule Pleroma.Web.RichMedia.Parser.TTL.OpengraphTest do
import Mox
+ alias Pleroma.Tests.ObanHelpers
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
alias Pleroma.Web.RichMedia.Card
@@ -36,6 +37,21 @@ defmodule Pleroma.Web.RichMedia.Parser.TTL.OpengraphTest do
Card.get_or_backfill_by_url(url)
- assert_enqueued(worker: Pleroma.Workers.RichMediaExpirationWorker, args: %{"url" => url})
+ # Find the backfill job
+ expected_job =
+ [
+ worker: "Pleroma.Workers.RichMediaWorker",
+ args: %{"op" => "backfill", "url" => url}
+ ]
+
+ assert_enqueued(expected_job)
+
+ # Run it manually
+ ObanHelpers.perform_all()
+
+ assert_enqueued(
+ worker: Pleroma.Workers.RichMediaWorker,
+ args: %{"op" => "expire", "url" => url}
+ )
end
end
diff --git a/test/pleroma/web/rich_media/parser_test.exs b/test/pleroma/web/rich_media/parser_test.exs
index 3fcb5c808..8fd75b57a 100644
--- a/test/pleroma/web/rich_media/parser_test.exs
+++ b/test/pleroma/web/rich_media/parser_test.exs
@@ -13,12 +13,14 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
end
+ setup_all do: clear_config([:rich_media, :enabled], true)
+
test "returns error when no metadata present" do
assert {:error, _} = Parser.parse("https://example.com/empty")
end
test "doesn't just add a title" do
- assert {:error, {:invalid_metadata, _}} = Parser.parse("https://example.com/non-ogp")
+ assert {:error, :invalid_metadata} = Parser.parse("https://example.com/non-ogp")
end
test "parses ogp" do
@@ -94,7 +96,7 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
end
test "returns error if getting page was not successful" do
- assert {:error, :overload} = Parser.parse("https://example.com/error")
+ assert {:error, :get} = Parser.parse("https://example.com/error")
end
test "does a HEAD request to check if the body is too large" do
@@ -102,17 +104,17 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
end
test "does a HEAD request to check if the body is html" do
- assert {:error, {:content_type, _}} = Parser.parse("https://example.com/pdf-file")
+ assert {:error, :content_type} = Parser.parse("https://example.com/pdf-file")
end
test "refuses to crawl incomplete URLs" do
url = "example.com/ogp"
- assert :error == Parser.parse(url)
+ assert {:error, :validate} == Parser.parse(url)
end
test "refuses to crawl malformed URLs" do
url = "example.com[]/ogp"
- assert :error == Parser.parse(url)
+ assert {:error, :validate} == Parser.parse(url)
end
test "refuses to crawl URLs of private network from posts" do
@@ -124,7 +126,13 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
"https://pleroma.local/notice/9kCP7V"
]
|> Enum.each(fn url ->
- assert :error == Parser.parse(url)
+ assert {:error, :validate} == Parser.parse(url)
end)
end
+
+ test "returns error when disabled" do
+ clear_config([:rich_media, :enabled], false)
+
+ assert match?({:error, :rich_media_disabled}, Parser.parse("https://example.com/ogp"))
+ end
end
diff --git a/test/pleroma/web/streamer_test.exs b/test/pleroma/web/streamer_test.exs
index d85358fd4..262ff11d2 100644
--- a/test/pleroma/web/streamer_test.exs
+++ b/test/pleroma/web/streamer_test.exs
@@ -418,7 +418,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
{:ok, activity} = CommonAPI.post(user, %{status: ":("})
- {:ok, _} = CommonAPI.favorite(blocked, activity.id)
+ {:ok, _} = CommonAPI.favorite(activity.id, blocked)
refute_receive _
end
@@ -430,11 +430,11 @@ defmodule Pleroma.Web.StreamerTest do
user2 = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "super hot take"})
- {:ok, _} = CommonAPI.add_mute(user, activity)
+ {:ok, _} = CommonAPI.add_mute(activity, user)
Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
- {:ok, favorite_activity} = CommonAPI.favorite(user2, activity.id)
+ {:ok, favorite_activity} = CommonAPI.favorite(activity.id, user2)
refute_receive _
assert Streamer.filtered_by_user?(user, favorite_activity)
@@ -448,7 +448,7 @@ defmodule Pleroma.Web.StreamerTest do
{:ok, activity} = CommonAPI.post(user, %{status: "super hot take"})
Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
- {:ok, favorite_activity} = CommonAPI.favorite(user2, activity.id)
+ {:ok, favorite_activity} = CommonAPI.favorite(activity.id, user2)
assert_receive {:render_with_user, _, "notification.json", notif, _}
assert notif.activity.id == favorite_activity.id
@@ -464,7 +464,7 @@ defmodule Pleroma.Web.StreamerTest do
{:ok, user} = User.block_domain(user, "hecking-lewd-place.com")
{:ok, activity} = CommonAPI.post(user, %{status: "super hot take"})
Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
- {:ok, favorite_activity} = CommonAPI.favorite(user2, activity.id)
+ {:ok, favorite_activity} = CommonAPI.favorite(activity.id, user2)
refute_receive _
assert Streamer.filtered_by_user?(user, favorite_activity)
@@ -477,7 +477,7 @@ defmodule Pleroma.Web.StreamerTest do
user2 = insert(:user)
Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
- {:ok, _follower, _followed, follow_activity} = CommonAPI.follow(user2, user)
+ {:ok, _follower, _followed, follow_activity} = CommonAPI.follow(user, user2)
assert_receive {:render_with_user, _, "notification.json", notif, _}
assert notif.activity.id == follow_activity.id
@@ -493,7 +493,7 @@ defmodule Pleroma.Web.StreamerTest do
other_user_id = other_user.id
Streamer.get_topic_and_add_socket("user", user, oauth_token)
- {:ok, _follower, _followed, _follow_activity} = CommonAPI.follow(user, other_user)
+ {:ok, _follower, _followed, _follow_activity} = CommonAPI.follow(other_user, user)
assert_receive {:text, event}
@@ -536,12 +536,12 @@ defmodule Pleroma.Web.StreamerTest do
test "it streams edits in the 'user' stream", %{user: user, token: oauth_token} do
sender = insert(:user)
- {:ok, _, _, _} = CommonAPI.follow(user, sender)
+ {:ok, _, _, _} = CommonAPI.follow(sender, user)
{:ok, activity} = CommonAPI.post(sender, %{status: "hey"})
Streamer.get_topic_and_add_socket("user", user, oauth_token)
- {:ok, edited} = CommonAPI.update(sender, activity, %{status: "mew mew"})
+ {:ok, edited} = CommonAPI.update(activity, sender, %{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, _}
@@ -552,7 +552,7 @@ defmodule Pleroma.Web.StreamerTest do
{:ok, activity} = CommonAPI.post(user, %{status: "hey"})
Streamer.get_topic_and_add_socket("user", user, oauth_token)
- {:ok, edited} = CommonAPI.update(user, activity, %{status: "mew mew"})
+ {:ok, edited} = CommonAPI.update(activity, user, %{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, _}
@@ -608,7 +608,7 @@ defmodule Pleroma.Web.StreamerTest do
{:ok, activity} = CommonAPI.post(sender, %{status: "hey"})
assert_receive {:text, _}
- {:ok, edited} = CommonAPI.update(sender, activity, %{status: "mew mew"})
+ {:ok, edited} = CommonAPI.update(activity, sender, %{status: "mew mew"})
edited = Pleroma.Activity.normalize(edited)
@@ -627,7 +627,7 @@ defmodule Pleroma.Web.StreamerTest do
{:ok, activity} = CommonAPI.post(sender, %{status: "hey"})
assert_receive {:text, _}
- {:ok, edited} = CommonAPI.update(sender, activity, %{status: "mew mew"})
+ {:ok, edited} = CommonAPI.update(activity, sender, %{status: "mew mew"})
edited = Pleroma.Activity.normalize(edited)
@@ -638,7 +638,7 @@ defmodule Pleroma.Web.StreamerTest do
assert %{"id" => ^activity_id} = Jason.decode!(payload)
refute Streamer.filtered_by_user?(sender, edited)
- {:ok, edited} = CommonAPI.update(sender, activity, %{status: "mew mew 2"})
+ {:ok, edited} = CommonAPI.update(activity, sender, %{status: "mew mew 2"})
edited = Pleroma.Activity.normalize(edited)
@@ -826,8 +826,8 @@ defmodule Pleroma.Web.StreamerTest do
test "it filters muted reblogs", %{user: user1, token: user1_token} do
user2 = insert(:user)
user3 = insert(:user)
- CommonAPI.follow(user1, user2)
- CommonAPI.hide_reblogs(user1, user2)
+ CommonAPI.follow(user2, user1)
+ CommonAPI.hide_reblogs(user2, user1)
{:ok, create_activity} = CommonAPI.post(user3, %{status: "I'm kawen"})
@@ -842,8 +842,8 @@ defmodule Pleroma.Web.StreamerTest do
token: user1_token
} do
user2 = insert(:user)
- CommonAPI.follow(user1, user2)
- CommonAPI.hide_reblogs(user1, user2)
+ CommonAPI.follow(user2, user1)
+ CommonAPI.hide_reblogs(user2, user1)
{:ok, create_activity} = CommonAPI.post(user1, %{status: "I'm kawen"})
Streamer.get_topic_and_add_socket("user", user1, user1_token)
@@ -858,12 +858,12 @@ defmodule Pleroma.Web.StreamerTest do
token: user1_token
} do
user2 = insert(:user)
- CommonAPI.follow(user1, user2)
- CommonAPI.hide_reblogs(user1, user2)
+ CommonAPI.follow(user2, user1)
+ CommonAPI.hide_reblogs(user2, user1)
{:ok, create_activity} = CommonAPI.post(user1, %{status: "I'm kawen"})
Streamer.get_topic_and_add_socket("user", user1, user1_token)
- {:ok, _favorite_activity} = CommonAPI.favorite(user2, create_activity.id)
+ {:ok, _favorite_activity} = CommonAPI.favorite(create_activity.id, user2)
assert_receive {:render_with_user, _, "notification.json", notif, _}
refute Streamer.filtered_by_user?(user1, notif)
@@ -876,9 +876,9 @@ defmodule Pleroma.Web.StreamerTest do
%{user: user2, token: user2_token} = oauth_access(["read"])
Streamer.get_topic_and_add_socket("user", user2, user2_token)
- {:ok, user2, user, _activity} = CommonAPI.follow(user2, user)
+ {:ok, user2, user, _activity} = CommonAPI.follow(user, user2)
{:ok, activity} = CommonAPI.post(user, %{status: "super hot take"})
- {:ok, _} = CommonAPI.add_mute(user2, activity)
+ {:ok, _} = CommonAPI.add_mute(activity, user2)
assert_receive {:render_with_user, _, _, ^activity, _}
assert Streamer.filtered_by_user?(user2, activity)
@@ -1026,8 +1026,8 @@ defmodule Pleroma.Web.StreamerTest do
%{user: user2, token: user2_token} = oauth_access(["read"])
post_user = insert(:user)
- CommonAPI.follow(user, post_user)
- CommonAPI.follow(user2, post_user)
+ CommonAPI.follow(post_user, user)
+ CommonAPI.follow(post_user, user2)
tasks = [
Task.async(child_proc.(starter.(user, token), hit)),
@@ -1058,7 +1058,7 @@ defmodule Pleroma.Web.StreamerTest do
%{user: user, token: token} = oauth_access(["read"])
post_user = insert(:user)
- CommonAPI.follow(user, post_user)
+ CommonAPI.follow(post_user, user)
tasks = [
Task.async(child_proc.(starter.(user, token), hit)),
diff --git a/test/pleroma/web/twitter_api/remote_follow_controller_test.exs b/test/pleroma/web/twitter_api/remote_follow_controller_test.exs
index c6ecb53f4..f762b1356 100644
--- a/test/pleroma/web/twitter_api/remote_follow_controller_test.exs
+++ b/test/pleroma/web/twitter_api/remote_follow_controller_test.exs
@@ -216,7 +216,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
test "returns success result when user already in followers", %{conn: conn} do
user = insert(:user)
user2 = insert(:user)
- {:ok, _, _, _} = CommonAPI.follow(user, user2)
+ {:ok, _, _, _} = CommonAPI.follow(user2, user)
conn =
conn
diff --git a/test/pleroma/web/web_finger_test.exs b/test/pleroma/web/web_finger_test.exs
index be5e08776..aefe7b0c2 100644
--- a/test/pleroma/web/web_finger_test.exs
+++ b/test/pleroma/web/web_finger_test.exs
@@ -76,15 +76,6 @@ defmodule Pleroma.Web.WebFingerTest do
{:ok, _data} = WebFinger.finger(user)
end
- test "returns the ActivityPub actor URI and subscribe address for an ActivityPub user with the ld+json mimetype" do
- user = "kaniini@gerzilla.de"
-
- {:ok, data} = WebFinger.finger(user)
-
- assert data["ap_id"] == "https://gerzilla.de/channel/kaniini"
- assert data["subscribe_address"] == "https://gerzilla.de/follow?f=&url={uri}"
- end
-
test "it work for AP-only user" do
user = "kpherox@mstdn.jp"
@@ -99,12 +90,6 @@ defmodule Pleroma.Web.WebFingerTest do
assert data["subscribe_address"] == "https://mstdn.jp/authorize_interaction?acct={uri}"
end
- test "it works for friendica" do
- user = "lain@squeet.me"
-
- {:ok, _data} = WebFinger.finger(user)
- end
-
test "it gets the xrd endpoint" do
{:ok, template} = WebFinger.find_lrdd_template("social.heldscal.la")
@@ -203,5 +188,43 @@ defmodule Pleroma.Web.WebFingerTest do
assert :error = WebFinger.finger("pekorino@pawoo.net")
end
+
+ test "prevents spoofing" do
+ Tesla.Mock.mock(fn
+ %{
+ url: "https://gleasonator.com/.well-known/webfinger?resource=acct:alex@gleasonator.com"
+ } ->
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/webfinger_spoof.json"),
+ headers: [{"content-type", "application/jrd+json"}]
+ }}
+
+ %{url: "https://gleasonator.com/.well-known/host-meta"} ->
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/gleasonator.com_host_meta")
+ }}
+ end)
+
+ {:error, _data} = WebFinger.finger("alex@gleasonator.com")
+ end
+ end
+
+ test "prevents forgeries" do
+ Tesla.Mock.mock(fn
+ %{url: "https://fba.ryona.agency/.well-known/webfinger?resource=acct:graf@fba.ryona.agency"} ->
+ fake_webfinger =
+ File.read!("test/fixtures/webfinger/graf-imposter-webfinger.json") |> Jason.decode!()
+
+ Tesla.Mock.json(fake_webfinger)
+
+ %{url: "https://fba.ryona.agency/.well-known/host-meta"} ->
+ {:ok, %Tesla.Env{status: 404}}
+ end)
+
+ assert {:error, _} = WebFinger.finger("graf@fba.ryona.agency")
end
end
diff --git a/test/pleroma/workers/poll_worker_test.exs b/test/pleroma/workers/poll_worker_test.exs
new file mode 100644
index 000000000..749df8aff
--- /dev/null
+++ b/test/pleroma/workers/poll_worker_test.exs
@@ -0,0 +1,49 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Workers.PollWorkerTest do
+ use Pleroma.DataCase
+ use Oban.Testing, repo: Pleroma.Repo
+
+ import Mock
+ import Pleroma.Factory
+
+ alias Pleroma.Workers.PollWorker
+
+ test "poll notification job" do
+ user = insert(:user)
+ question = insert(:question, user: user)
+ activity = insert(:question_activity, question: question)
+
+ PollWorker.schedule_poll_end(activity)
+
+ expected_job_args = %{"activity_id" => activity.id, "op" => "poll_end"}
+
+ assert_enqueued(args: expected_job_args)
+
+ with_mocks([
+ {
+ Pleroma.Web.Streamer,
+ [],
+ [
+ stream: fn _, _ -> nil end
+ ]
+ },
+ {
+ Pleroma.Web.Push,
+ [],
+ [
+ send: fn _ -> nil end
+ ]
+ }
+ ]) do
+ [job] = all_enqueued(worker: PollWorker)
+ PollWorker.perform(job)
+
+ # Ensure notifications were streamed out when job executes
+ assert called(Pleroma.Web.Streamer.stream(["user", "user:notification"], :_))
+ assert called(Pleroma.Web.Push.send(:_))
+ end
+ end
+end
diff --git a/test/pleroma/workers/purge_expired_activity_test.exs b/test/pleroma/workers/purge_expired_activity_test.exs
index 0372f54ca..040ff6a51 100644
--- a/test/pleroma/workers/purge_expired_activity_test.exs
+++ b/test/pleroma/workers/purge_expired_activity_test.exs
@@ -42,7 +42,7 @@ defmodule Pleroma.Workers.PurgeExpiredActivityTest do
user = Pleroma.User.get_by_ap_id(activity.actor)
Pleroma.Repo.delete(user)
- assert {:error, :user_not_found} =
+ assert {:cancel, :user_not_found} =
perform_job(Pleroma.Workers.PurgeExpiredActivity, %{activity_id: activity.id})
end
@@ -53,7 +53,7 @@ defmodule Pleroma.Workers.PurgeExpiredActivityTest do
expires_at: DateTime.add(DateTime.utc_now(), 3601)
})
- assert {:error, :activity_not_found} =
+ assert {:cancel, :activity_not_found} =
perform_job(Pleroma.Workers.PurgeExpiredActivity, %{activity_id: "some_if"})
end
end
diff --git a/test/pleroma/workers/receiver_worker_test.exs b/test/pleroma/workers/receiver_worker_test.exs
index b9b6d6af2..33be91085 100644
--- a/test/pleroma/workers/receiver_worker_test.exs
+++ b/test/pleroma/workers/receiver_worker_test.exs
@@ -9,6 +9,7 @@ defmodule Pleroma.Workers.ReceiverWorkerTest do
import Mock
import Pleroma.Factory
+ alias Pleroma.Web.Federator
alias Pleroma.Workers.ReceiverWorker
test "it does not retry MRF reject" do
@@ -16,7 +17,7 @@ defmodule Pleroma.Workers.ReceiverWorkerTest do
with_mock Pleroma.Web.ActivityPub.Transmogrifier,
handle_incoming: fn _ -> {:reject, "MRF"} end do
- assert {:cancel, "MRF"} =
+ assert {:cancel, {:reject, "MRF"}} =
ReceiverWorker.perform(%Oban.Job{
args: %{"op" => "incoming_ap_doc", "params" => params}
})
@@ -49,4 +50,199 @@ defmodule Pleroma.Workers.ReceiverWorkerTest do
args: %{"op" => "incoming_ap_doc", "params" => params}
})
end
+
+ test "it can validate the signature" do
+ Tesla.Mock.mock(fn
+ %{url: "https://mastodon.social/users/bastianallgeier"} ->
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/bastianallgeier.json"),
+ headers: [{"content-type", "application/activity+json"}]
+ }
+
+ %{url: "https://mastodon.social/users/bastianallgeier/collections/featured"} ->
+ %Tesla.Env{
+ status: 200,
+ headers: [{"content-type", "application/activity+json"}],
+ body:
+ File.read!("test/fixtures/users_mock/masto_featured.json")
+ |> String.replace("{{domain}}", "mastodon.social")
+ |> String.replace("{{nickname}}", "bastianallgeier")
+ }
+
+ %{url: "https://phpc.social/users/denniskoch"} ->
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/denniskoch.json"),
+ headers: [{"content-type", "application/activity+json"}]
+ }
+
+ %{url: "https://phpc.social/users/denniskoch/collections/featured"} ->
+ %Tesla.Env{
+ status: 200,
+ headers: [{"content-type", "application/activity+json"}],
+ body:
+ File.read!("test/fixtures/users_mock/masto_featured.json")
+ |> String.replace("{{domain}}", "phpc.social")
+ |> String.replace("{{nickname}}", "denniskoch")
+ }
+
+ %{url: "https://mastodon.social/users/bastianallgeier/statuses/112846516276907281"} ->
+ %Tesla.Env{
+ status: 200,
+ headers: [{"content-type", "application/activity+json"}],
+ body: File.read!("test/fixtures/receiver_worker_signature_activity.json")
+ }
+ end)
+
+ params = %{
+ "@context" => [
+ "https://www.w3.org/ns/activitystreams",
+ "https://w3id.org/security/v1",
+ %{
+ "claim" => %{"@id" => "toot:claim", "@type" => "@id"},
+ "memorial" => "toot:memorial",
+ "atomUri" => "ostatus:atomUri",
+ "manuallyApprovesFollowers" => "as:manuallyApprovesFollowers",
+ "blurhash" => "toot:blurhash",
+ "ostatus" => "http://ostatus.org#",
+ "discoverable" => "toot:discoverable",
+ "focalPoint" => %{"@container" => "@list", "@id" => "toot:focalPoint"},
+ "votersCount" => "toot:votersCount",
+ "Hashtag" => "as:Hashtag",
+ "Emoji" => "toot:Emoji",
+ "alsoKnownAs" => %{"@id" => "as:alsoKnownAs", "@type" => "@id"},
+ "sensitive" => "as:sensitive",
+ "movedTo" => %{"@id" => "as:movedTo", "@type" => "@id"},
+ "inReplyToAtomUri" => "ostatus:inReplyToAtomUri",
+ "conversation" => "ostatus:conversation",
+ "Device" => "toot:Device",
+ "schema" => "http://schema.org#",
+ "toot" => "http://joinmastodon.org/ns#",
+ "cipherText" => "toot:cipherText",
+ "suspended" => "toot:suspended",
+ "messageType" => "toot:messageType",
+ "featuredTags" => %{"@id" => "toot:featuredTags", "@type" => "@id"},
+ "Curve25519Key" => "toot:Curve25519Key",
+ "deviceId" => "toot:deviceId",
+ "Ed25519Signature" => "toot:Ed25519Signature",
+ "featured" => %{"@id" => "toot:featured", "@type" => "@id"},
+ "devices" => %{"@id" => "toot:devices", "@type" => "@id"},
+ "value" => "schema:value",
+ "PropertyValue" => "schema:PropertyValue",
+ "messageFranking" => "toot:messageFranking",
+ "publicKeyBase64" => "toot:publicKeyBase64",
+ "identityKey" => %{"@id" => "toot:identityKey", "@type" => "@id"},
+ "Ed25519Key" => "toot:Ed25519Key",
+ "indexable" => "toot:indexable",
+ "EncryptedMessage" => "toot:EncryptedMessage",
+ "fingerprintKey" => %{"@id" => "toot:fingerprintKey", "@type" => "@id"}
+ }
+ ],
+ "actor" => "https://phpc.social/users/denniskoch",
+ "cc" => [
+ "https://phpc.social/users/denniskoch/followers",
+ "https://mastodon.social/users/bastianallgeier",
+ "https://chaos.social/users/distantnative",
+ "https://fosstodon.org/users/kev"
+ ],
+ "id" => "https://phpc.social/users/denniskoch/statuses/112847382711461301/activity",
+ "object" => %{
+ "atomUri" => "https://phpc.social/users/denniskoch/statuses/112847382711461301",
+ "attachment" => [],
+ "attributedTo" => "https://phpc.social/users/denniskoch",
+ "cc" => [
+ "https://phpc.social/users/denniskoch/followers",
+ "https://mastodon.social/users/bastianallgeier",
+ "https://chaos.social/users/distantnative",
+ "https://fosstodon.org/users/kev"
+ ],
+ "content" =>
+ "<p><span class=\"h-card\" translate=\"no\"><a href=\"https://mastodon.social/@bastianallgeier\" class=\"u-url mention\">@<span>bastianallgeier</span></a></span> <span class=\"h-card\" translate=\"no\"><a href=\"https://chaos.social/@distantnative\" class=\"u-url mention\">@<span>distantnative</span></a></span> <span class=\"h-card\" translate=\"no\"><a href=\"https://fosstodon.org/@kev\" class=\"u-url mention\">@<span>kev</span></a></span> Another main argument: Discord is popular. Many people have an account, so you can just join an server quickly. Also you know the app and how to get around.</p>",
+ "contentMap" => %{
+ "en" =>
+ "<p><span class=\"h-card\" translate=\"no\"><a href=\"https://mastodon.social/@bastianallgeier\" class=\"u-url mention\">@<span>bastianallgeier</span></a></span> <span class=\"h-card\" translate=\"no\"><a href=\"https://chaos.social/@distantnative\" class=\"u-url mention\">@<span>distantnative</span></a></span> <span class=\"h-card\" translate=\"no\"><a href=\"https://fosstodon.org/@kev\" class=\"u-url mention\">@<span>kev</span></a></span> Another main argument: Discord is popular. Many people have an account, so you can just join an server quickly. Also you know the app and how to get around.</p>"
+ },
+ "conversation" =>
+ "tag:mastodon.social,2024-07-25:objectId=760068442:objectType=Conversation",
+ "id" => "https://phpc.social/users/denniskoch/statuses/112847382711461301",
+ "inReplyTo" =>
+ "https://mastodon.social/users/bastianallgeier/statuses/112846516276907281",
+ "inReplyToAtomUri" =>
+ "https://mastodon.social/users/bastianallgeier/statuses/112846516276907281",
+ "published" => "2024-07-25T13:33:29Z",
+ "replies" => %{
+ "first" => %{
+ "items" => [],
+ "next" =>
+ "https://phpc.social/users/denniskoch/statuses/112847382711461301/replies?only_other_accounts=true&page=true",
+ "partOf" =>
+ "https://phpc.social/users/denniskoch/statuses/112847382711461301/replies",
+ "type" => "CollectionPage"
+ },
+ "id" => "https://phpc.social/users/denniskoch/statuses/112847382711461301/replies",
+ "type" => "Collection"
+ },
+ "sensitive" => false,
+ "tag" => [
+ %{
+ "href" => "https://mastodon.social/users/bastianallgeier",
+ "name" => "@bastianallgeier@mastodon.social",
+ "type" => "Mention"
+ },
+ %{
+ "href" => "https://chaos.social/users/distantnative",
+ "name" => "@distantnative@chaos.social",
+ "type" => "Mention"
+ },
+ %{
+ "href" => "https://fosstodon.org/users/kev",
+ "name" => "@kev@fosstodon.org",
+ "type" => "Mention"
+ }
+ ],
+ "to" => ["https://www.w3.org/ns/activitystreams#Public"],
+ "type" => "Note",
+ "url" => "https://phpc.social/@denniskoch/112847382711461301"
+ },
+ "published" => "2024-07-25T13:33:29Z",
+ "signature" => %{
+ "created" => "2024-07-25T13:33:29Z",
+ "creator" => "https://phpc.social/users/denniskoch#main-key",
+ "signatureValue" =>
+ "slz9BKJzd2n1S44wdXGOU+bV/wsskdgAaUpwxj8R16mYOL8+DTpE6VnfSKoZGsBBJT8uG5gnVfVEz1YsTUYtymeUgLMh7cvd8VnJnZPS+oixbmBRVky/Myf91TEgQQE7G4vDmTdB4ii54hZrHcOOYYf5FKPNRSkMXboKA6LMqNtekhbI+JTUJYIB02WBBK6PUyo15f6B1RJ6HGWVgud9NE0y1EZXfrkqUt682p8/9D49ORf7AwjXUJibKic2RbPvhEBj70qUGfBm4vvgdWhSUn1IG46xh+U0+NrTSUED82j1ZVOeua/2k/igkGs8cSBkY35quXTkPz6gbqCCH66CuA==",
+ "type" => "RsaSignature2017"
+ },
+ "to" => ["https://www.w3.org/ns/activitystreams#Public"],
+ "type" => "Create"
+ }
+
+ req_headers = [
+ ["accept-encoding", "gzip"],
+ ["content-length", "5184"],
+ ["content-type", "application/activity+json"],
+ ["date", "Thu, 25 Jul 2024 13:33:31 GMT"],
+ ["digest", "SHA-256=ouge/6HP2/QryG6F3JNtZ6vzs/hSwMk67xdxe87eH7A="],
+ ["host", "bikeshed.party"],
+ [
+ "signature",
+ "keyId=\"https://mastodon.social/users/bastianallgeier#main-key\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date digest content-type\",signature=\"ymE3vn5Iw50N6ukSp8oIuXJB5SBjGAGjBasdTDvn+ahZIzq2SIJfmVCsIIzyqIROnhWyQoTbavTclVojEqdaeOx+Ejz2wBnRBmhz5oemJLk4RnnCH0lwMWyzeY98YAvxi9Rq57Gojuv/1lBqyGa+rDzynyJpAMyFk17XIZpjMKuTNMCbjMDy76ILHqArykAIL/v1zxkgwxY/+ELzxqMpNqtZ+kQ29znNMUBB3eVZ/mNAHAz6o33Y9VKxM2jw+08vtuIZOusXyiHbRiaj2g5HtN2WBUw1MzzfRfHF2/yy7rcipobeoyk5RvP5SyHV3WrIeZ3iyoNfmv33y8fxllF0EA==\""
+ ],
+ [
+ "user-agent",
+ "http.rb/5.2.0 (Mastodon/4.3.0-nightly.2024-07-25; +https://mastodon.social/)"
+ ]
+ ]
+
+ {:ok, oban_job} =
+ Federator.incoming_ap_doc(%{
+ method: "POST",
+ req_headers: req_headers,
+ request_path: "/inbox",
+ params: params,
+ query_string: ""
+ })
+
+ assert {:ok, %Pleroma.Activity{}} = ReceiverWorker.perform(oban_job)
+ end
end
diff --git a/test/pleroma/workers/remote_fetcher_worker_test.exs b/test/pleroma/workers/remote_fetcher_worker_test.exs
index c30e773d4..2104baab2 100644
--- a/test/pleroma/workers/remote_fetcher_worker_test.exs
+++ b/test/pleroma/workers/remote_fetcher_worker_test.exs
@@ -39,19 +39,19 @@ defmodule Pleroma.Workers.RemoteFetcherWorkerTest do
end
test "does not requeue a deleted object" do
- assert {:discard, _} =
+ assert {:cancel, _} =
RemoteFetcherWorker.perform(%Oban.Job{
args: %{"op" => "fetch_remote", "id" => @deleted_object_one}
})
- assert {:discard, _} =
+ assert {:cancel, _} =
RemoteFetcherWorker.perform(%Oban.Job{
args: %{"op" => "fetch_remote", "id" => @deleted_object_two}
})
end
test "does not requeue an unauthorized object" do
- assert {:discard, _} =
+ assert {:cancel, _} =
RemoteFetcherWorker.perform(%Oban.Job{
args: %{"op" => "fetch_remote", "id" => @unauthorized_object}
})
@@ -60,7 +60,7 @@ defmodule Pleroma.Workers.RemoteFetcherWorkerTest do
test "does not requeue an object that exceeded depth" do
clear_config([:instance, :federation_incoming_replies_max_depth], 0)
- assert {:discard, _} =
+ assert {:cancel, _} =
RemoteFetcherWorker.perform(%Oban.Job{
args: %{"op" => "fetch_remote", "id" => @depth_object, "depth" => 1}
})
diff --git a/test/support/data_case.ex b/test/support/data_case.ex
index 14403f0b8..52d4bef1a 100644
--- a/test/support/data_case.ex
+++ b/test/support/data_case.ex
@@ -116,6 +116,7 @@ defmodule Pleroma.DataCase do
Mox.stub_with(Pleroma.Web.FederatorMock, Pleroma.Web.Federator)
Mox.stub_with(Pleroma.ConfigMock, Pleroma.Config)
Mox.stub_with(Pleroma.StaticStubbedConfigMock, Pleroma.Test.StaticConfig)
+ Mox.stub_with(Pleroma.StubbedHTTPSignaturesMock, Pleroma.Test.HTTPSignaturesProxy)
end
def ensure_local_uploader(context) do
diff --git a/test/support/factory.ex b/test/support/factory.ex
index 20bc5162e..b248508fa 100644
--- a/test/support/factory.ex
+++ b/test/support/factory.ex
@@ -249,6 +249,7 @@ defmodule Pleroma.Factory do
"cc" => [user.follower_address],
"context" => Pleroma.Web.ActivityPub.Utils.generate_context_id(),
"closed" => DateTime.utc_now() |> DateTime.add(86_400) |> DateTime.to_iso8601(),
+ "content" => "Which flavor of ice cream do you prefer?",
"oneOf" => [
%{
"type" => "Note",
diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex
index f656c9412..ed044cf98 100644
--- a/test/support/http_request_mock.ex
+++ b/test/support/http_request_mock.ex
@@ -1521,6 +1521,120 @@ defmodule HttpRequestMock do
}}
end
+ def get("https://mastodon.example/.well-known/host-meta", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 302,
+ headers: [{"location", "https://sub.mastodon.example/.well-known/host-meta"}]
+ }}
+ end
+
+ def get("https://sub.mastodon.example/.well-known/host-meta", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body:
+ "test/fixtures/webfinger/masto-host-meta.xml"
+ |> File.read!()
+ |> String.replace("{{domain}}", "sub.mastodon.example")
+ }}
+ end
+
+ def get(
+ "https://sub.mastodon.example/.well-known/webfinger?resource=acct:a@mastodon.example",
+ _,
+ _,
+ _
+ ) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body:
+ "test/fixtures/webfinger/masto-webfinger.json"
+ |> File.read!()
+ |> String.replace("{{nickname}}", "a")
+ |> String.replace("{{domain}}", "mastodon.example")
+ |> String.replace("{{subdomain}}", "sub.mastodon.example"),
+ headers: [{"content-type", "application/jrd+json"}]
+ }}
+ end
+
+ def get("https://sub.mastodon.example/users/a", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body:
+ "test/fixtures/webfinger/masto-user.json"
+ |> File.read!()
+ |> String.replace("{{nickname}}", "a")
+ |> String.replace("{{domain}}", "sub.mastodon.example"),
+ headers: [{"content-type", "application/activity+json"}]
+ }}
+ end
+
+ def get("https://sub.mastodon.example/users/a/collections/featured", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body:
+ File.read!("test/fixtures/users_mock/masto_featured.json")
+ |> String.replace("{{domain}}", "sub.mastodon.example")
+ |> String.replace("{{nickname}}", "a"),
+ headers: [{"content-type", "application/activity+json"}]
+ }}
+ end
+
+ def get("https://pleroma.example/.well-known/host-meta", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 302,
+ headers: [{"location", "https://sub.pleroma.example/.well-known/host-meta"}]
+ }}
+ end
+
+ def get("https://sub.pleroma.example/.well-known/host-meta", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body:
+ "test/fixtures/webfinger/pleroma-host-meta.xml"
+ |> File.read!()
+ |> String.replace("{{domain}}", "sub.pleroma.example")
+ }}
+ end
+
+ def get(
+ "https://sub.pleroma.example/.well-known/webfinger?resource=acct:a@pleroma.example",
+ _,
+ _,
+ _
+ ) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body:
+ "test/fixtures/webfinger/pleroma-webfinger.json"
+ |> File.read!()
+ |> String.replace("{{nickname}}", "a")
+ |> String.replace("{{domain}}", "pleroma.example")
+ |> String.replace("{{subdomain}}", "sub.pleroma.example"),
+ headers: [{"content-type", "application/jrd+json"}]
+ }}
+ end
+
+ def get("https://sub.pleroma.example/users/a", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body:
+ "test/fixtures/webfinger/pleroma-user.json"
+ |> File.read!()
+ |> String.replace("{{nickname}}", "a")
+ |> String.replace("{{domain}}", "sub.pleroma.example"),
+ headers: [{"content-type", "application/activity+json"}]
+ }}
+ end
+
def get(url, query, body, headers) do
{:error,
"Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{inspect(headers)}"}
@@ -1610,7 +1724,7 @@ defmodule HttpRequestMock do
]
def head(url, _query, _body, _headers) when url in @rich_media_mocks do
- {:ok, %Tesla.Env{status: 404, body: ""}}
+ {:ok, %Tesla.Env{status: 200, body: ""}}
end
def head("https://example.com/pdf-file", _, _, _) do
diff --git a/test/support/http_signatures_proxy.ex b/test/support/http_signatures_proxy.ex
new file mode 100644
index 000000000..4c6b39d19
--- /dev/null
+++ b/test/support/http_signatures_proxy.ex
@@ -0,0 +1,9 @@
+defmodule Pleroma.Test.HTTPSignaturesProxy do
+ @behaviour Pleroma.HTTPSignaturesAPI
+
+ @impl true
+ defdelegate validate_conn(conn), to: HTTPSignatures
+
+ @impl true
+ defdelegate signature_for_conn(conn), to: HTTPSignatures
+end
diff --git a/test/support/mocks.ex b/test/support/mocks.ex
index d906f0e1d..63cbc49ab 100644
--- a/test/support/mocks.ex
+++ b/test/support/mocks.ex
@@ -28,6 +28,7 @@ Mox.defmock(Pleroma.Web.FederatorMock, for: Pleroma.Web.Federator.Publishing)
Mox.defmock(Pleroma.ConfigMock, for: Pleroma.Config.Getting)
Mox.defmock(Pleroma.UnstubbedConfigMock, for: Pleroma.Config.Getting)
Mox.defmock(Pleroma.StaticStubbedConfigMock, for: Pleroma.Config.Getting)
+Mox.defmock(Pleroma.StubbedHTTPSignaturesMock, for: Pleroma.HTTPSignaturesAPI)
Mox.defmock(Pleroma.LoggerMock, for: Pleroma.Logging)
diff --git a/test/test_helper.exs b/test/test_helper.exs
index a117584ae..fed7ce8a7 100644
--- a/test/test_helper.exs
+++ b/test/test_helper.exs
@@ -4,9 +4,9 @@
Code.put_compiler_option(:warnings_as_errors, true)
-ExUnit.configure(max_cases: System.schedulers_online())
+ExUnit.configure(capture_log: true, max_cases: System.schedulers_online())
-ExUnit.start(exclude: [:federated, :erratic])
+ExUnit.start(exclude: [:federated])
if match?({:unix, :darwin}, :os.type()) do
excluded = ExUnit.configuration() |> Keyword.get(:exclude, [])