\n"
"Language-Team: Japanese \n"
+"pleroma-backend-domain-errors/ja/>\n"
"Language: ja\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.6.2\n"
+"X-Generator: Weblate 4.13.1\n"
## This file is a PO Template file.
##
@@ -25,11 +25,11 @@ msgstr ""
## effect: edit them in PO (`.po`) files instead.
## From Ecto.Changeset.cast/4
msgid "can't be blank"
-msgstr ""
+msgstr "空にすることはできません"
## From Ecto.Changeset.unique_constraint/3
msgid "has already been taken"
-msgstr ""
+msgstr "すでに使用されています"
## From Ecto.Changeset.put_change/3
msgid "is invalid"
@@ -37,7 +37,7 @@ msgstr ""
## From Ecto.Changeset.validate_format/3
msgid "has invalid format"
-msgstr ""
+msgstr "書式が正しくありません"
## From Ecto.Changeset.validate_subset/3
msgid "has an invalid entry"
@@ -45,7 +45,7 @@ msgstr ""
## From Ecto.Changeset.validate_exclusion/3
msgid "is reserved"
-msgstr ""
+msgstr "予約されています"
## From Ecto.Changeset.validate_confirmation/3
msgid "does not match confirmation"
@@ -61,23 +61,23 @@ msgstr ""
## From Ecto.Changeset.validate_length/3
msgid "should be %{count} character(s)"
msgid_plural "should be %{count} character(s)"
-msgstr[0] ""
+msgstr[0] "%{count}文字である必要があります"
msgid "should have %{count} item(s)"
msgid_plural "should have %{count} item(s)"
-msgstr[0] ""
+msgstr[0] "%{count}個の要素を含む必要があります"
msgid "should be at least %{count} character(s)"
msgid_plural "should be at least %{count} character(s)"
-msgstr[0] ""
+msgstr[0] "%{count}文字以上である必要があります"
msgid "should have at least %{count} item(s)"
msgid_plural "should have at least %{count} item(s)"
-msgstr[0] ""
+msgstr[0] "%{count}個以上の要素を含む必要があります"
msgid "should be at most %{count} character(s)"
msgid_plural "should be at most %{count} character(s)"
-msgstr[0] ""
+msgstr[0] "%{count}文字以下である必要があります"
msgid "should have at most %{count} item(s)"
msgid_plural "should have at most %{count} item(s)"
@@ -102,7 +102,7 @@ msgstr "%{number}でなければなりません"
#: lib/pleroma/web/common_api/common_api.ex:505
#, elixir-format
msgid "Account not found"
-msgstr "アカウントがありません"
+msgstr "アカウントが見つかりません"
#: lib/pleroma/web/common_api/common_api.ex:339
#, elixir-format
@@ -226,7 +226,7 @@ msgstr ""
#: lib/pleroma/web/common_api/utils.ex:414
#, elixir-format
msgid "Invalid password."
-msgstr ""
+msgstr "パスワードが間違っています。"
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:220
#, elixir-format
@@ -236,7 +236,7 @@ msgstr ""
#: lib/pleroma/web/twitter_api/twitter_api.ex:109
#, elixir-format
msgid "Kocaptcha service unavailable"
-msgstr ""
+msgstr "Kocaptchaが利用できません"
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:112
#, elixir-format
@@ -259,12 +259,12 @@ msgstr ""
#: lib/pleroma/web/feed/user_controller.ex:71 lib/pleroma/web/ostatus/ostatus_controller.ex:143
#, elixir-format
msgid "Not found"
-msgstr ""
+msgstr "見つかりません"
#: lib/pleroma/web/common_api/common_api.ex:331
#, elixir-format
msgid "Poll's author can't vote"
-msgstr ""
+msgstr "作成者は投票できません"
#: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:20
#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:37 lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:49
@@ -284,17 +284,17 @@ msgstr ""
#: lib/pleroma/web/common_api/activity_draft.ex:107
#, elixir-format
msgid "The message visibility must be direct"
-msgstr ""
+msgstr "公開範囲は「ダイレクト」でなければいけません"
#: lib/pleroma/web/common_api/utils.ex:573
#, elixir-format
msgid "The status is over the character limit"
-msgstr ""
+msgstr "文字数制限を超過しています"
#: lib/pleroma/plugs/ensure_public_or_authenticated_plug.ex:31
#, elixir-format
msgid "This resource requires authentication."
-msgstr ""
+msgstr "認証が必要です。"
#: lib/pleroma/plugs/rate_limiter/rate_limiter.ex:206
#, elixir-format
@@ -304,7 +304,7 @@ msgstr ""
#: lib/pleroma/web/common_api/common_api.ex:356
#, elixir-format
msgid "Too many choices"
-msgstr ""
+msgstr "選択肢が多すぎます"
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:443
#, elixir-format
@@ -320,7 +320,7 @@ msgstr ""
#: lib/pleroma/web/oauth/oauth_controller.ex:308
#, elixir-format
msgid "Your account is currently disabled"
-msgstr ""
+msgstr "あなたのアカウントは無効化されています"
#: lib/pleroma/web/oauth/oauth_controller.ex:183
#: lib/pleroma/web/oauth/oauth_controller.ex:331
@@ -331,23 +331,23 @@ msgstr ""
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:390
#, elixir-format
msgid "can't read inbox of %{nickname} as %{as_nickname}"
-msgstr ""
+msgstr "%{nickname}のinboxを%{as_nickname}として閲覧することはできません"
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:473
#, elixir-format
msgid "can't update outbox of %{nickname} as %{as_nickname}"
-msgstr ""
+msgstr "%{nickname}のoutboxを%{as_nickname}として更新することはできません"
#: lib/pleroma/web/common_api/common_api.ex:471
#, elixir-format
msgid "conversation is already muted"
-msgstr ""
+msgstr "この会話はミュート済みです"
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:314
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:492
#, elixir-format
msgid "error"
-msgstr ""
+msgstr "エラー"
#: lib/pleroma/web/pleroma_api/controllers/mascot_controller.ex:32
#, elixir-format
@@ -357,7 +357,7 @@ msgstr ""
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:62
#, elixir-format
msgid "not found"
-msgstr ""
+msgstr "見つかりません"
#: lib/pleroma/web/oauth/oauth_controller.ex:394
#, elixir-format
@@ -382,28 +382,28 @@ msgstr ""
#: lib/pleroma/web/oauth/oauth_controller.ex:410
#, elixir-format
msgid "Failed to authenticate: %{message}."
-msgstr ""
+msgstr "認証に失敗しました: %{message}。"
#: lib/pleroma/web/oauth/oauth_controller.ex:441
#, elixir-format
msgid "Failed to set up user account."
-msgstr ""
+msgstr "ユーザーアカウントの設定に失敗しました。"
#: lib/pleroma/plugs/oauth_scopes_plug.ex:38
#, elixir-format
msgid "Insufficient permissions: %{permissions}."
-msgstr ""
+msgstr "%{permissions}の権限が必要です。"
#: lib/pleroma/plugs/uploaded_media.ex:104
#, elixir-format
msgid "Internal Error"
-msgstr ""
+msgstr "内部エラー"
#: lib/pleroma/web/oauth/fallback_controller.ex:22
#: lib/pleroma/web/oauth/fallback_controller.ex:29
#, elixir-format
msgid "Invalid Username/Password"
-msgstr ""
+msgstr "ユーザー名/パスワードが間違っています"
#: lib/pleroma/web/twitter_api/twitter_api.ex:118
#, elixir-format
@@ -423,7 +423,7 @@ msgstr ""
#: lib/pleroma/web/oauth/fallback_controller.ex:14
#, elixir-format
msgid "Unknown error, please check the details and try again."
-msgstr ""
+msgstr "不明なエラーです。詳細を確認し、再度試行してください。"
#: lib/pleroma/web/oauth/oauth_controller.ex:119
#: lib/pleroma/web/oauth/oauth_controller.ex:158
@@ -449,17 +449,17 @@ msgstr ""
#: lib/pleroma/web/twitter_api/twitter_api.ex:103
#, elixir-format
msgid "CAPTCHA Error"
-msgstr ""
+msgstr "CAPTCHAエラー"
#: lib/pleroma/web/common_api/common_api.ex:290
#, elixir-format
msgid "Could not add reaction emoji"
-msgstr ""
+msgstr "リアクションを追加できません"
#: lib/pleroma/web/common_api/common_api.ex:301
#, elixir-format
msgid "Could not remove reaction emoji"
-msgstr ""
+msgstr "リアクションを解除できません"
#: lib/pleroma/web/twitter_api/twitter_api.ex:129
#, elixir-format
@@ -469,7 +469,7 @@ msgstr ""
#: lib/pleroma/web/mastodon_api/controllers/list_controller.ex:92
#, elixir-format
msgid "List not found"
-msgstr ""
+msgstr "リストが見つかりません"
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:123
#, elixir-format
@@ -480,7 +480,7 @@ msgstr ""
#: lib/pleroma/web/oauth/oauth_controller.ex:321
#, elixir-format
msgid "Password reset is required"
-msgstr ""
+msgstr "パスワードのリセットが必要です"
#: lib/pleroma/tests/auth_test_controller.ex:9
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:6 lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:6
@@ -522,7 +522,7 @@ msgstr ""
#: lib/pleroma/plugs/ensure_authenticated_plug.ex:28
#, elixir-format
msgid "Two-factor authentication enabled, you must use a access token."
-msgstr ""
+msgstr "二段階認証が有効になっています。アクセストークンが必要です。"
#: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:210
#, elixir-format
@@ -552,7 +552,7 @@ msgstr ""
#: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:61
#, elixir-format
msgid "Web push subscription is disabled on this Pleroma instance"
-msgstr ""
+msgstr "このPleromaインスタンスではプッシュ通知が利用できません"
#: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:451
#, elixir-format
@@ -562,19 +562,19 @@ msgstr ""
#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:126
#, elixir-format
msgid "authorization required for timeline view"
-msgstr ""
+msgstr "タイムラインを閲覧するには認証が必要です"
#: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:24
#, elixir-format
msgid "Access denied"
-msgstr ""
+msgstr "アクセスが拒否されました"
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:282
#, elixir-format
msgid "This API requires an authenticated user"
-msgstr ""
+msgstr "このAPIを利用するには認証が必要です"
#: lib/pleroma/plugs/user_is_admin_plug.ex:21
#, elixir-format
msgid "User is not an admin."
-msgstr ""
+msgstr "ユーザーは管理者ではありません。"
diff --git a/priv/repo/migrations/20240223165000_create_bookmark_folders.exs b/priv/repo/migrations/20240223165000_create_bookmark_folders.exs
new file mode 100644
index 000000000..016916968
--- /dev/null
+++ b/priv/repo/migrations/20240223165000_create_bookmark_folders.exs
@@ -0,0 +1,27 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2024 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Repo.Migrations.CreateBookmarkFolders do
+ use Ecto.Migration
+
+ def change do
+ create_if_not_exists table(:bookmark_folders, primary_key: false) do
+ add(:id, :uuid, primary_key: true)
+ add(:name, :string, null: false)
+ add(:emoji, :string)
+ add(:user_id, references(:users, type: :uuid, on_delete: :delete_all))
+
+ timestamps()
+ end
+
+ alter table(:bookmarks) do
+ add_if_not_exists(
+ :folder_id,
+ references(:bookmark_folders, type: :uuid, on_delete: :nilify_all)
+ )
+ end
+
+ create_if_not_exists(unique_index(:bookmark_folders, [:user_id, :name]))
+ end
+end
diff --git a/priv/static/schemas/litepub-0.1.jsonld b/priv/static/schemas/litepub-0.1.jsonld
index b499a96f5..d156cba55 100644
--- a/priv/static/schemas/litepub-0.1.jsonld
+++ b/priv/static/schemas/litepub-0.1.jsonld
@@ -40,7 +40,9 @@
"@type": "@id"
},
"vcard": "http://www.w3.org/2006/vcard/ns#",
- "formerRepresentations": "litepub:formerRepresentations"
+ "formerRepresentations": "litepub:formerRepresentations",
+ "sm": "http://smithereen.software/ns#",
+ "nonAnonymous": "sm:nonAnonymous"
}
]
}
diff --git a/test/fixtures/ccworld-ap-bridge_note.json b/test/fixtures/ccworld-ap-bridge_note.json
new file mode 100644
index 000000000..4b13b4bc1
--- /dev/null
+++ b/test/fixtures/ccworld-ap-bridge_note.json
@@ -0,0 +1 @@
+{"@context":"https://www.w3.org/ns/activitystreams","type":"Note","id":"https://cc.mkdir.uk/ap/note/e5d1d0a1-1ab3-4498-9949-588e3fdea286","attributedTo":"https://cc.mkdir.uk/ap/acct/hiira","inReplyTo":"","quoteUrl":"","content":"おはコンー","published":"2024-01-19T22:08:05Z","to":["https://www.w3.org/ns/activitystreams#Public"],"tag":null,"attachment":[],"object":null}
diff --git a/test/fixtures/minds-invalid-mention-post.json b/test/fixtures/minds-invalid-mention-post.json
new file mode 100644
index 000000000..ea2cb2739
--- /dev/null
+++ b/test/fixtures/minds-invalid-mention-post.json
@@ -0,0 +1 @@
+{"@context":"https://www.w3.org/ns/activitystreams","type":"Note","id":"https://www.minds.com/api/activitypub/users/1198929502760083472/entities/urn:comment:1600926863310458883:0:0:0:1600932467852709903","attributedTo":"https://www.minds.com/api/activitypub/users/1198929502760083472","content":"\u003Ca class=\u0022u-url mention\u0022 href=\u0022https://www.minds.com/lain\u0022 target=\u0022_blank\u0022\u003E@lain\u003C/a\u003E corn syrup.","to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://www.minds.com/api/activitypub/users/1198929502760083472/followers","https://lain.com/users/lain"],"tag":[{"type":"Mention","href":"https://www.minds.com/api/activitypub/users/464237775479123984","name":"@lain"}],"url":"https://www.minds.com/newsfeed/1600926863310458883?focusedCommentUrn=urn:comment:1600926863310458883:0:0:0:1600932467852709903","published":"2024-02-04T17:34:03+00:00","inReplyTo":"https://lain.com/objects/36254095-c839-4167-bcc2-b361d5de9198","source":{"content":"@lain corn syrup.","mediaType":"text/plain"}}
\ No newline at end of file
diff --git a/test/fixtures/minds-pleroma-mentioned-post.json b/test/fixtures/minds-pleroma-mentioned-post.json
new file mode 100644
index 000000000..9dfa42c90
--- /dev/null
+++ b/test/fixtures/minds-pleroma-mentioned-post.json
@@ -0,0 +1 @@
+{"@context":["https://www.w3.org/ns/activitystreams","https://lain.com/schemas/litepub-0.1.jsonld",{"@language":"und"}],"actor":"https://lain.com/users/lain","attachment":[],"attributedTo":"https://lain.com/users/lain","cc":["https://lain.com/users/lain/followers"],"content":"which diet is the best for cognitive dissonance","context":"https://lain.com/contexts/98c8a130-e813-4797-8973-600e80114317","conversation":"https://lain.com/contexts/98c8a130-e813-4797-8973-600e80114317","id":"https://lain.com/objects/36254095-c839-4167-bcc2-b361d5de9198","published":"2024-02-04T17:11:23.931890Z","repliesCount":11,"sensitive":null,"source":{"content":"which diet is the best for cognitive dissonance","mediaType":"text/plain"},"summary":"","tag":[],"to":["https://www.w3.org/ns/activitystreams#Public"],"type":"Note"}
\ No newline at end of file
diff --git a/test/fixtures/tesla_mock/smithereen_non_anonymous_poll.json b/test/fixtures/tesla_mock/smithereen_non_anonymous_poll.json
new file mode 100644
index 000000000..2b343ea64
--- /dev/null
+++ b/test/fixtures/tesla_mock/smithereen_non_anonymous_poll.json
@@ -0,0 +1 @@
+{"type":"Question","id":"https://friends.grishka.me/posts/54642","attributedTo":"https://friends.grishka.me/users/1","content":"здесь тоже можно что-то написать отдельно от опроса
","published":"2021-09-04T00:22:16Z","url":"https://friends.grishka.me/posts/54642","to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://friends.grishka.me/users/1/followers"],"replies":{"type":"Collection","id":"https://friends.grishka.me/posts/54642/replies","first":{"type":"CollectionPage","items":[],"partOf":"https://friends.grishka.me/posts/54642/replies","next":"https://friends.grishka.me/posts/54642/replies?page=1"}},"sensitive":false,"likes":"https://friends.grishka.me/posts/54642/likes","name":"тестовый опрос","oneOf":[{"type":"Note","id":"https://friends.grishka.me/posts/54642#options/76","name":"тестовый ответ 1","replies":{"type":"Collection","id":"https://friends.grishka.me/activitypub/objects/polls/24/options/76/votes","totalItems":4,"items":[]}},{"type":"Note","id":"https://friends.grishka.me/posts/54642#options/77","name":"тестовый ответ 2","replies":{"type":"Collection","id":"https://friends.grishka.me/activitypub/objects/polls/24/options/77/votes","totalItems":4,"items":[]}},{"type":"Note","id":"https://friends.grishka.me/posts/54642#options/78","name":"тестовый ответ 3","replies":{"type":"Collection","id":"https://friends.grishka.me/activitypub/objects/polls/24/options/78/votes","totalItems":6,"items":[]}}],"votersCount":14,"nonAnonymous":true,"@context":["https://www.w3.org/ns/activitystreams",{"sensitive":"as:sensitive","toot":"http://joinmastodon.org/ns#","sm":"http://smithereen.software/ns#","votersCount":"toot:votersCount","nonAnonymous":"sm:nonAnonymous"}]}
\ No newline at end of file
diff --git a/test/fixtures/tesla_mock/smithereen_user.json b/test/fixtures/tesla_mock/smithereen_user.json
new file mode 100644
index 000000000..6468fc519
--- /dev/null
+++ b/test/fixtures/tesla_mock/smithereen_user.json
@@ -0,0 +1 @@
+{"type":"Person","id":"https://friends.grishka.me/users/1","name":"Григорий Клюшников","icon":{"type":"Image","image":{"type":"Image","url":"https://friends.grishka.me/i/6QLsOws97AWp5N_osd74C1IC1ijnFopyCBD9MSEeXNQ/q:93/bG9jYWw6Ly8vcy91cGxvYWRzL2F2YXRhcnMvNTYzODRhODEwODk5ZTRjMzI4YmY4YmQwM2Q2MWM3NmMud2VicA.jpg","mediaType":"image/jpeg","width":1280,"height":960},"width":573,"height":572,"cropRegion":[0.26422762870788574,0.3766937553882599,0.7113820910453796,0.9728997349739075],"url":"https://friends.grishka.me/i/ql_49PQcETAWgY_nC-Qj63H_Oa6FyOAEoWFkUSSkUvQ/c:573:572:nowe:338:362/q:93/bG9jYWw6Ly8vcy91cGxvYWRzL2F2YXRhcnMvNTYzODRhODEwODk5ZTRjMzI4YmY4YmQwM2Q2MWM3NmMud2VicA.jpg","mediaType":"image/jpeg"},"summary":"Делаю эту хрень, пытаюсь вырвать социальные сети из жадных лап корпораций
\n\n\n\n\n\n\n\nThis server does NOT support direct messages. Please write me on Telegram or Matrix.
","url":"https://friends.grishka.me/grishka","preferredUsername":"grishka","inbox":"https://friends.grishka.me/users/1/inbox","outbox":"https://friends.grishka.me/users/1/outbox","followers":"https://friends.grishka.me/users/1/followers","following":"https://friends.grishka.me/users/1/following","endpoints":{"sharedInbox":"https://friends.grishka.me/activitypub/sharedInbox","collectionSimpleQuery":"https://friends.grishka.me/users/1/collectionQuery"},"publicKey":{"id":"https://friends.grishka.me/users/1#main-key","owner":"https://friends.grishka.me/users/1","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjlakm+i/d9ER/hIeR7KfiFW+SdLZj2SkKIeM8cmR+YFJuh9ghFqXrkFEjcaqUnAFqe5gYDNSQACnDLA8y4DnzjfGNIohKAnRoa9x6GORmfKQvcnjaTZ53S1NvUiPPyc0Pv/vfCtY/Ab0CEXe5BLqL38oZn817Jf7pBrPRTYH7m012kvwAUTT6k0Y8lPITBEG7nzYbbuGcrN9Y/RDdwE08jmBXlZ45bahRH3VNXVpQE17dCzJB+7k+iJ1R7YCoI+DuMlBYGXGE2KVk46NZTuLnOjFV9SyXfWX4/SrJM4oxev+SX2N75tQgmNZmVVHeqg2ZcbC0WCfNjJOi2HHS9MujwIDAQAB\n-----END PUBLIC KEY-----\n"},"wall":"https://friends.grishka.me/users/1/wall","firstName":"Григорий","lastName":"Клюшников","middleName":"Александрович","vcard:bday":"1993-01-22","gender":"http://schema.org#Male","supportsFriendRequests":true,"friends":"https://friends.grishka.me/users/1/friends","groups":"https://friends.grishka.me/users/1/groups","capabilities":{"supportsFriendRequests":true},"@context":["https://www.w3.org/ns/activitystreams",{"sm":"http://smithereen.software/ns#","cropRegion":{"@id":"sm:cropRegion","@container":"@list"},"wall":{"@id":"sm:wall","@type":"@id"},"collectionSimpleQuery":"sm:collectionSimpleQuery","sc":"http://schema.org#","firstName":"sc:givenName","lastName":"sc:familyName","middleName":"sc:additionalName","gender":{"@id":"sc:gender","@type":"sc:GenderType"},"maidenName":"sm:maidenName","friends":{"@id":"sm:friends","@type":"@id"},"groups":{"@id":"sm:groups","@type":"@id"},"vcard":"http://www.w3.org/2006/vcard/ns#","capabilities":"litepub:capabilities","supportsFriendRequests":"sm:supportsFriendRequests","litepub":"http://litepub.social/ns#"},"https://w3id.org/security/v1"]}
\ No newline at end of file
diff --git a/test/pleroma/bookmark_folder_test.exs b/test/pleroma/bookmark_folder_test.exs
new file mode 100644
index 000000000..c45129b0e
--- /dev/null
+++ b/test/pleroma/bookmark_folder_test.exs
@@ -0,0 +1,60 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2024 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.BookmarkFolderTest do
+ use Pleroma.DataCase, async: true
+ import Pleroma.Factory
+ alias Pleroma.BookmarkFolder
+
+ describe "create/3" do
+ test "with valid params" do
+ user = insert(:user)
+ {:ok, folder} = BookmarkFolder.create(user.id, "Read later", "🕓")
+ assert folder.user_id == user.id
+ assert folder.name == "Read later"
+ assert folder.emoji == "🕓"
+ end
+
+ test "with invalid params" do
+ {:error, changeset} = BookmarkFolder.create(nil, "", "not an emoji")
+ refute changeset.valid?
+
+ assert changeset.errors == [
+ emoji: {"Invalid emoji", []},
+ user_id: {"can't be blank", [validation: :required]},
+ name: {"can't be blank", [validation: :required]}
+ ]
+ end
+ end
+
+ test "update/3" do
+ user = insert(:user)
+ {:ok, folder} = BookmarkFolder.create(user.id, "Read ltaer")
+ {:ok, folder} = BookmarkFolder.update(folder.id, "Read later")
+ assert folder.name == "Read later"
+ end
+
+ test "for_user/1" do
+ user = insert(:user)
+ other_user = insert(:user)
+
+ {:ok, _} = BookmarkFolder.create(user.id, "Folder 1")
+ {:ok, _} = BookmarkFolder.create(user.id, "Folder 2")
+ {:ok, _} = BookmarkFolder.create(other_user.id, "Folder 3")
+
+ folders = BookmarkFolder.for_user(user.id)
+
+ assert length(folders) == 2
+ end
+
+ test "belongs_to_user?/2" do
+ user = insert(:user)
+ other_user = insert(:user)
+
+ {:ok, folder} = BookmarkFolder.create(user.id, "Folder")
+
+ assert true == BookmarkFolder.belongs_to_user?(folder.id, user.id)
+ assert false == BookmarkFolder.belongs_to_user?(folder.id, other_user.id)
+ end
+end
diff --git a/test/pleroma/bookmark_test.exs b/test/pleroma/bookmark_test.exs
index 57144ded3..a2ed24c26 100644
--- a/test/pleroma/bookmark_test.exs
+++ b/test/pleroma/bookmark_test.exs
@@ -6,15 +6,17 @@ defmodule Pleroma.BookmarkTest do
use Pleroma.DataCase, async: true
import Pleroma.Factory
alias Pleroma.Bookmark
+ alias Pleroma.BookmarkFolder
alias Pleroma.Web.CommonAPI
- describe "create/2" do
+ describe "create/3" do
test "with valid params" do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "Some cool information"})
{:ok, bookmark} = Bookmark.create(user.id, activity.id)
assert bookmark.user_id == user.id
assert bookmark.activity_id == activity.id
+ assert bookmark.folder_id == nil
end
test "with invalid params" do
@@ -26,6 +28,19 @@ defmodule Pleroma.BookmarkTest do
activity_id: {"can't be blank", [validation: :required]}
]
end
+
+ test "update existing bookmark folder" do
+ user = insert(:user)
+ {:ok, activity} = CommonAPI.post(user, %{status: "Some cool information"})
+
+ {:ok, bookmark} = Bookmark.create(user.id, activity.id)
+ assert bookmark.folder_id == nil
+
+ {:ok, bookmark_folder} = BookmarkFolder.create(user.id, "Read later")
+
+ {:ok, bookmark} = Bookmark.create(user.id, activity.id, bookmark_folder.id)
+ assert bookmark.folder_id == bookmark_folder.id
+ end
end
describe "destroy/2" do
diff --git a/test/pleroma/integration/mastodon_websocket_test.exs b/test/pleroma/integration/mastodon_websocket_test.exs
index a2c20f0a6..a0ffddf8d 100644
--- a/test/pleroma/integration/mastodon_websocket_test.exs
+++ b/test/pleroma/integration/mastodon_websocket_test.exs
@@ -268,17 +268,6 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
end)
end
- test "accepts valid token on Sec-WebSocket-Protocol header", %{token: token} do
- assert {:ok, _} = start_socket("?stream=user", [{"Sec-WebSocket-Protocol", token.token}])
-
- capture_log(fn ->
- assert {:error, %WebSockex.RequestError{code: 401}} =
- start_socket("?stream=user", [{"Sec-WebSocket-Protocol", "I am a friend"}])
-
- Process.sleep(30)
- end)
- end
-
test "accepts valid token on client-sent event", %{token: token} do
assert {:ok, pid} = start_socket()
diff --git a/test/pleroma/maps_test.exs b/test/pleroma/maps_test.exs
new file mode 100644
index 000000000..05f1b18b2
--- /dev/null
+++ b/test/pleroma/maps_test.exs
@@ -0,0 +1,22 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2024 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.MapsTest do
+ use Pleroma.DataCase, async: true
+
+ alias Pleroma.Maps
+
+ describe "filter_empty_values/1" do
+ assert %{"bar" => "b", "ray" => ["foo"], "objs" => %{"a" => "b"}} ==
+ Maps.filter_empty_values(%{
+ "foo" => nil,
+ "fooz" => "",
+ "bar" => "b",
+ "rei" => [],
+ "ray" => ["foo"],
+ "obj" => %{},
+ "objs" => %{"a" => "b"}
+ })
+ end
+end
diff --git a/test/pleroma/search/database_search_test.exs b/test/pleroma/search/database_search_test.exs
index 6c47ff425..d8dd09063 100644
--- a/test/pleroma/search/database_search_test.exs
+++ b/test/pleroma/search/database_search_test.exs
@@ -35,21 +35,6 @@ defmodule Pleroma.Search.DatabaseSearchTest do
assert [] = Search.search(nil, "wednesday")
end
- test "using plainto_tsquery on postgres < 11" do
- old_version = :persistent_term.get({Pleroma.Repo, :postgres_version})
- :persistent_term.put({Pleroma.Repo, :postgres_version}, 10.0)
- on_exit(fn -> :persistent_term.put({Pleroma.Repo, :postgres_version}, old_version) end)
-
- user = insert(:user)
- {:ok, post} = CommonAPI.post(user, %{status: "it's wednesday my dudes"})
- {:ok, _post2} = CommonAPI.post(user, %{status: "it's wednesday my bros"})
-
- # plainto doesn't understand complex queries
- assert [result] = Search.search(nil, "wednesday -dudes")
-
- assert result.id == post.id
- end
-
test "using websearch_to_tsquery" do
user = insert(:user)
{:ok, _post} = CommonAPI.post(user, %{status: "it's wednesday my dudes"})
diff --git a/test/pleroma/user/backup_test.exs b/test/pleroma/user/backup_test.exs
index 0ac57e334..5503d15bc 100644
--- a/test/pleroma/user/backup_test.exs
+++ b/test/pleroma/user/backup_test.exs
@@ -166,6 +166,7 @@ defmodule Pleroma.User.BackupTest do
test "it creates a zip archive with user data" do
user = insert(:user, %{nickname: "cofe", name: "Cofe", ap_id: "http://cofe.io/users/cofe"})
+ %{ap_id: other_ap_id} = other_user = insert(:user)
{:ok, %{object: %{data: %{"id" => id1}}} = status1} =
CommonAPI.post(user, %{status: "status1"})
@@ -182,6 +183,8 @@ defmodule Pleroma.User.BackupTest do
Bookmark.create(user.id, status2.id)
Bookmark.create(user.id, status3.id)
+ CommonAPI.follow(user, other_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])
@@ -261,6 +264,16 @@ defmodule Pleroma.User.BackupTest do
"type" => "OrderedCollection"
} = Jason.decode!(json)
+ assert {:ok, {'following.json', json}} = :zip.zip_get('following.json', zipfile)
+
+ assert %{
+ "@context" => "https://www.w3.org/ns/activitystreams",
+ "id" => "following.json",
+ "orderedItems" => [^other_ap_id],
+ "totalItems" => 1,
+ "type" => "OrderedCollection"
+ } = Jason.decode!(json)
+
:zip.zip_close(zipfile)
File.rm!(path)
end
diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs
index d8c09c975..6f975575a 100644
--- a/test/pleroma/user_test.exs
+++ b/test/pleroma/user_test.exs
@@ -2977,4 +2977,51 @@ defmodule Pleroma.UserTest do
refute User.endorses?(user, pinned_user)
end
end
+
+ test "it checks fields links for a backlink" do
+ user = insert(:user, ap_id: "https://social.example.org/users/lain")
+
+ fields = [
+ %{"name" => "Link", "value" => "http://example.com/rel_me/null"},
+ %{"name" => "Verified link", "value" => "http://example.com/rel_me/link"},
+ %{"name" => "Not a link", "value" => "i'm not a link"}
+ ]
+
+ user
+ |> User.update_and_set_cache(%{raw_fields: fields})
+
+ ObanHelpers.perform_all()
+
+ user = User.get_cached_by_id(user.id)
+
+ assert [
+ %{"verified_at" => nil},
+ %{"verified_at" => verified_at},
+ %{"verified_at" => nil}
+ ] = user.fields
+
+ assert is_binary(verified_at)
+ end
+
+ test "updating fields does not invalidate previously validated links" do
+ user = insert(:user, ap_id: "https://social.example.org/users/lain")
+
+ user
+ |> User.update_and_set_cache(%{
+ raw_fields: [%{"name" => "verified link", "value" => "http://example.com/rel_me/link"}]
+ })
+
+ ObanHelpers.perform_all()
+
+ %User{fields: [%{"verified_at" => verified_at}]} = user = User.get_cached_by_id(user.id)
+
+ user
+ |> User.update_and_set_cache(%{
+ raw_fields: [%{"name" => "Verified link", "value" => "http://example.com/rel_me/link"}]
+ })
+
+ user = User.get_cached_by_id(user.id)
+
+ assert [%{"verified_at" => ^verified_at}] = user.fields
+ end
end
diff --git a/test/pleroma/web/activity_pub/mrf/force_mention_test.exs b/test/pleroma/web/activity_pub/mrf/force_mention_test.exs
new file mode 100644
index 000000000..b026bab66
--- /dev/null
+++ b/test/pleroma/web/activity_pub/mrf/force_mention_test.exs
@@ -0,0 +1,73 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2024 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionTest do
+ use Pleroma.DataCase
+ require Pleroma.Constants
+
+ alias Pleroma.Web.ActivityPub.MRF.ForceMention
+
+ import Pleroma.Factory
+
+ test "adds mention to a reply" do
+ lain =
+ insert(:user, ap_id: "https://lain.com/users/lain", nickname: "lain@lain.com", local: false)
+
+ niobleoum =
+ insert(:user,
+ ap_id: "https://www.minds.com/api/activitypub/users/1198929502760083472",
+ nickname: "niobleoum@minds.com",
+ local: false
+ )
+
+ status = File.read!("test/fixtures/minds-pleroma-mentioned-post.json") |> Jason.decode!()
+
+ status_activity = %{
+ "type" => "Create",
+ "actor" => lain.ap_id,
+ "object" => status
+ }
+
+ Pleroma.Web.ActivityPub.Transmogrifier.handle_incoming(status_activity)
+
+ reply = File.read!("test/fixtures/minds-invalid-mention-post.json") |> Jason.decode!()
+
+ reply_activity = %{
+ "type" => "Create",
+ "actor" => niobleoum.ap_id,
+ "object" => reply
+ }
+
+ {:ok, %{"object" => %{"tag" => tag}}} = ForceMention.filter(reply_activity)
+
+ assert Enum.find(tag, fn %{"href" => href} -> href == lain.ap_id end)
+ end
+
+ test "adds mention to a quote" do
+ user1 = insert(:user, ap_id: "https://misskey.io/users/83ssedkv53")
+ user2 = insert(:user, ap_id: "https://misskey.io/users/7rkrarq81i")
+
+ status = File.read!("test/fixtures/tesla_mock/misskey.io_8vs6wxufd0.json") |> Jason.decode!()
+
+ status_activity = %{
+ "type" => "Create",
+ "actor" => user1.ap_id,
+ "object" => status
+ }
+
+ Pleroma.Web.ActivityPub.Transmogrifier.handle_incoming(status_activity)
+
+ quote_post = File.read!("test/fixtures/quote_post/misskey_quote_post.json") |> Jason.decode!()
+
+ quote_activity = %{
+ "type" => "Create",
+ "actor" => user2.ap_id,
+ "object" => quote_post
+ }
+
+ {:ok, %{"object" => %{"tag" => tag}}} = ForceMention.filter(quote_activity)
+
+ assert Enum.find(tag, fn %{"href" => href} -> href == user1.ap_id end)
+ end
+end
diff --git a/test/pleroma/web/activity_pub/mrf/steal_emoji_policy_test.exs b/test/pleroma/web/activity_pub/mrf/steal_emoji_policy_test.exs
index c477a093d..2c7497da5 100644
--- a/test/pleroma/web/activity_pub/mrf/steal_emoji_policy_test.exs
+++ b/test/pleroma/web/activity_pub/mrf/steal_emoji_policy_test.exs
@@ -87,6 +87,32 @@ defmodule Pleroma.Web.ActivityPub.MRF.StealEmojiPolicyTest do
assert File.exists?(fullpath)
end
+ test "rejects invalid shortcodes", %{path: path} do
+ message = %{
+ "type" => "Create",
+ "object" => %{
+ "emoji" => [{"fired/fox", "https://example.org/emoji/firedfox"}],
+ "actor" => "https://example.org/users/admin"
+ }
+ }
+
+ fullpath = Path.join(path, "fired/fox.png")
+
+ Tesla.Mock.mock(fn %{method: :get, url: "https://example.org/emoji/firedfox"} ->
+ %Tesla.Env{status: 200, body: File.read!("test/fixtures/image.jpg")}
+ end)
+
+ clear_config(:mrf_steal_emoji, hosts: ["example.org"], size_limit: 284_468)
+
+ refute "firedfox" in installed()
+ refute File.exists?(path)
+
+ assert {:ok, _message} = StealEmojiPolicy.filter(message)
+
+ refute "fired/fox" in installed()
+ refute File.exists?(fullpath)
+ end
+
test "reject regex shortcode", %{message: message} do
refute "firedfox" in installed()
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 4703c3801..2b33950d6 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
@@ -93,6 +93,17 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidatorTest
%{valid?: true} = ArticleNotePageValidator.cast_and_validate(note)
end
+ test "a Note from Convergence AP Bridge validates" do
+ insert(:user, ap_id: "https://cc.mkdir.uk/ap/acct/hiira")
+
+ note =
+ "test/fixtures/ccworld-ap-bridge_note.json"
+ |> File.read!()
+ |> Jason.decode!()
+
+ %{valid?: true} = ArticleNotePageValidator.cast_and_validate(note)
+ end
+
test "a note with an attachment should work", _ do
insert(:user, %{ap_id: "https://owncast.localhost.localdomain/federation/user/streamer"})
diff --git a/test/pleroma/web/activity_pub/publisher_test.exs b/test/pleroma/web/activity_pub/publisher_test.exs
index 7aa06a5c4..870f1f77a 100644
--- a/test/pleroma/web/activity_pub/publisher_test.exs
+++ b/test/pleroma/web/activity_pub/publisher_test.exs
@@ -25,6 +25,17 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
setup_all do: clear_config([:instance, :federating], true)
+ describe "should_federate?/1" do
+ test "it returns false when the inbox is nil" do
+ refute Publisher.should_federate?(nil, false)
+ refute Publisher.should_federate?(nil, true)
+ end
+
+ test "it returns true when public is true" do
+ assert Publisher.should_federate?(false, true)
+ end
+ end
+
describe "gather_webfinger_links/1" do
test "it returns links" do
user = insert(:user)
@@ -205,6 +216,7 @@ 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],
diff --git a/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs
index 44fdc5a24..9b635aed4 100644
--- a/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs
@@ -107,6 +107,18 @@ defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do
|> json_response_and_validate_schema(200)
end
+ test "get instance contact information", %{conn: conn} do
+ user = insert(:user, %{local: true})
+
+ clear_config([:instance, :contact_username], user.nickname)
+
+ conn = get(conn, "/api/v1/instance")
+
+ assert result = json_response_and_validate_schema(conn, 200)
+
+ assert result["contact_account"]["id"] == user.id
+ end
+
test "get instance information v2", %{conn: conn} do
clear_config([:auth, :oauth_consumer_strategies], [])
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 b05487abe..ad4144da4 100644
--- a/test/pleroma/web/mastodon_api/controllers/search_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/search_controller_test.exs
@@ -322,26 +322,20 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
end
test "search fetches remote statuses and prefers them over other results", %{conn: conn} do
- old_version = :persistent_term.get({Pleroma.Repo, :postgres_version})
- :persistent_term.put({Pleroma.Repo, :postgres_version}, 10.0)
- on_exit(fn -> :persistent_term.put({Pleroma.Repo, :postgres_version}, old_version) end)
+ {:ok, %{id: activity_id}} =
+ CommonAPI.post(insert(:user), %{
+ status: "check out http://mastodon.example.org/@admin/99541947525187367"
+ })
- capture_log(fn ->
- {:ok, %{id: activity_id}} =
- CommonAPI.post(insert(:user), %{
- status: "check out http://mastodon.example.org/@admin/99541947525187367"
- })
+ %{"url" => result_url, "id" => result_id} =
+ conn
+ |> get("/api/v1/search?q=http://mastodon.example.org/@admin/99541947525187367")
+ |> json_response_and_validate_schema(200)
+ |> Map.get("statuses")
+ |> List.first()
- results =
- conn
- |> get("/api/v1/search?q=http://mastodon.example.org/@admin/99541947525187367")
- |> json_response_and_validate_schema(200)
-
- assert [
- %{"url" => "http://mastodon.example.org/@admin/99541947525187367"},
- %{"id" => ^activity_id}
- ] = results["statuses"]
- end)
+ refute match?(^result_id, activity_id)
+ assert match?(^result_url, "http://mastodon.example.org/@admin/99541947525187367")
end
test "search doesn't show statuses that it shouldn't", %{conn: conn} do
diff --git a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
index f95f15ec3..3d8a0fa99 100644
--- a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
@@ -1828,6 +1828,60 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
json_response_and_validate_schema(bookmarks, 200)
end
+ test "bookmark folders" do
+ %{conn: conn, user: user} = oauth_access(["write:bookmarks", "read:bookmarks"])
+
+ {:ok, folder} = Pleroma.BookmarkFolder.create(user.id, "folder")
+ author = insert(:user)
+
+ folder_bookmarks_uri = "/api/v1/bookmarks?folder_id=#{folder.id}"
+
+ {:ok, activity1} = CommonAPI.post(author, %{status: "heweoo?"})
+ {:ok, activity2} = CommonAPI.post(author, %{status: "heweoo!"})
+
+ # Add bookmark with a folder
+ response =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/statuses/#{activity1.id}/bookmark", %{folder_id: folder.id})
+
+ assert json_response_and_validate_schema(response, 200)["bookmarked"] == true
+
+ assert json_response_and_validate_schema(response, 200)["pleroma"]["bookmark_folder"] ==
+ folder.id
+
+ response =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/statuses/#{activity2.id}/bookmark")
+
+ assert json_response_and_validate_schema(response, 200)["bookmarked"] == true
+ assert json_response_and_validate_schema(response, 200)["pleroma"]["bookmark_folder"] == nil
+
+ bookmarks =
+ get(conn, folder_bookmarks_uri)
+ |> json_response_and_validate_schema(200)
+
+ assert length(bookmarks) == 1
+
+ # Update folder for existing bookmark
+ response =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/statuses/#{activity2.id}/bookmark", %{folder_id: folder.id})
+
+ assert json_response_and_validate_schema(response, 200)["bookmarked"] == true
+
+ assert json_response_and_validate_schema(response, 200)["pleroma"]["bookmark_folder"] ==
+ folder.id
+
+ bookmarks =
+ get(conn, folder_bookmarks_uri)
+ |> json_response_and_validate_schema(200)
+
+ assert length(bookmarks) == 2
+ end
+
describe "conversation muting" do
setup do: oauth_access(["write:mutes"])
diff --git a/test/pleroma/web/mastodon_api/update_credentials_test.exs b/test/pleroma/web/mastodon_api/update_credentials_test.exs
index cf26cd9a6..bea0cae69 100644
--- a/test/pleroma/web/mastodon_api/update_credentials_test.exs
+++ b/test/pleroma/web/mastodon_api/update_credentials_test.exs
@@ -511,10 +511,15 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|> json_response_and_validate_schema(200)
assert account_data["fields"] == [
- %{"name" => "foo", "value" => "bar"},
+ %{
+ "name" => "foo",
+ "value" => "bar",
+ "verified_at" => nil
+ },
%{
"name" => "link.io",
- "value" => ~S(cofe.io)
+ "value" => ~S(cofe.io),
+ "verified_at" => nil
}
]
@@ -573,8 +578,8 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|> json_response_and_validate_schema(200)
assert account_data["fields"] == [
- %{"name" => ":firefox:", "value" => "is best 2hu"},
- %{"name" => "they wins", "value" => ":blank:"}
+ %{"name" => ":firefox:", "value" => "is best 2hu", "verified_at" => nil},
+ %{"name" => "they wins", "value" => ":blank:", "verified_at" => nil}
]
assert account_data["source"]["fields"] == [
@@ -602,10 +607,11 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|> json_response_and_validate_schema(200)
assert account["fields"] == [
- %{"name" => "foo", "value" => "bar"},
+ %{"name" => "foo", "value" => "bar", "verified_at" => nil},
%{
"name" => "link",
- "value" => ~S(http://cofe.io)
+ "value" => ~S(http://cofe.io),
+ "verified_at" => nil
}
]
@@ -627,7 +633,7 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|> json_response_and_validate_schema(200)
assert account["fields"] == [
- %{"name" => "foo", "value" => ""}
+ %{"name" => "foo", "value" => "", "verified_at" => nil}
]
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 a73d862fd..3aa73c224 100644
--- a/test/pleroma/web/mastodon_api/views/poll_view_test.exs
+++ b/test/pleroma/web/mastodon_api/views/poll_view_test.exs
@@ -43,7 +43,8 @@ defmodule Pleroma.Web.MastodonAPI.PollViewTest do
%{title: "why are you even asking?", votes_count: 0}
],
votes_count: 0,
- voters_count: 0
+ voters_count: 0,
+ pleroma: %{non_anonymous: false}
}
result = PollView.render("show.json", %{object: object})
@@ -165,4 +166,11 @@ defmodule Pleroma.Web.MastodonAPI.PollViewTest do
]
} = PollView.render("show.json", %{object: object})
end
+
+ test "that poll is non anonymous" do
+ object = Object.normalize("https://friends.grishka.me/posts/54642", fetch: true)
+ result = PollView.render("show.json", %{object: object})
+
+ assert result[:pleroma][:non_anonymous] == true
+ end
end
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 d82eeb7af..f007bb317 100644
--- a/test/pleroma/web/mastodon_api/views/status_view_test.exs
+++ b/test/pleroma/web/mastodon_api/views/status_view_test.exs
@@ -341,7 +341,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
emoji_reactions: [],
parent_visible: false,
pinned_at: nil,
- quotes_count: 0
+ quotes_count: 0,
+ bookmark_folder: nil
}
}
diff --git a/test/pleroma/web/pleroma_api/controllers/bookmark_folder_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/bookmark_folder_controller_test.exs
new file mode 100644
index 000000000..9bd90ed2e
--- /dev/null
+++ b/test/pleroma/web/pleroma_api/controllers/bookmark_folder_controller_test.exs
@@ -0,0 +1,161 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2024 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+defmodule Pleroma.Web.PleromaAPI.BookmarkFolderControllerTest do
+ use Pleroma.Web.ConnCase
+
+ alias Pleroma.BookmarkFolder
+ # alias Pleroma.Object
+ # alias Pleroma.Tests.Helpers
+ # alias Pleroma.UnstubbedConfigMock, as: ConfigMock
+ # alias Pleroma.User
+ # alias Pleroma.Web.ActivityPub.ActivityPub
+ # alias Pleroma.Web.CommonAPI
+
+ # import Mox
+ import Pleroma.Factory
+
+ describe "GET /api/v1/pleroma/bookmark_folders" do
+ setup do: oauth_access(["read:bookmarks"])
+
+ test "it lists bookmark folders", %{conn: conn, user: user} do
+ {:ok, folder} = BookmarkFolder.create(user.id, "Bookmark folder")
+
+ folder_id = folder.id
+
+ result =
+ conn
+ |> get("/api/v1/pleroma/bookmark_folders")
+ |> json_response_and_validate_schema(200)
+
+ assert [
+ %{
+ "id" => ^folder_id,
+ "name" => "Bookmark folder",
+ "emoji" => nil,
+ "emoji_url" => nil
+ }
+ ] = result
+ end
+ end
+
+ describe "POST /api/v1/pleroma/bookmark_folders" do
+ setup do: oauth_access(["write:bookmarks"])
+
+ test "it creates a bookmark folder", %{conn: conn} do
+ result =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/pleroma/bookmark_folders", %{
+ name: "Bookmark folder",
+ emoji: "📁"
+ })
+ |> json_response_and_validate_schema(200)
+
+ assert %{
+ "name" => "Bookmark folder",
+ "emoji" => "📁",
+ "emoji_url" => nil
+ } = result
+ end
+
+ test "it creates a bookmark folder with custom emoji", %{conn: conn} do
+ result =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/pleroma/bookmark_folders", %{
+ name: "Bookmark folder",
+ emoji: ":firefox:"
+ })
+ |> json_response_and_validate_schema(200)
+
+ assert %{
+ "name" => "Bookmark folder",
+ "emoji" => ":firefox:",
+ "emoji_url" => "http://localhost:4001/emoji/Firefox.gif"
+ } = result
+ end
+
+ test "it returns error for invalid emoji", %{conn: conn} do
+ result =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/pleroma/bookmark_folders", %{
+ name: "Bookmark folder",
+ emoji: "not an emoji"
+ })
+ |> json_response_and_validate_schema(422)
+
+ assert %{"error" => "Invalid emoji"} = result
+ end
+ end
+
+ describe "PATCH /api/v1/pleroma/bookmark_folders/:id" do
+ setup do: oauth_access(["write:bookmarks"])
+
+ test "it updates a bookmark folder", %{conn: conn, user: user} do
+ {:ok, folder} = BookmarkFolder.create(user.id, "Bookmark folder")
+
+ result =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> patch("/api/v1/pleroma/bookmark_folders/#{folder.id}", %{
+ name: "bookmark folder"
+ })
+ |> json_response_and_validate_schema(200)
+
+ assert %{
+ "name" => "bookmark folder"
+ } = result
+ end
+
+ test "it returns error when updating others' folders", %{conn: conn} do
+ other_user = insert(:user)
+
+ {:ok, folder} = BookmarkFolder.create(other_user.id, "Bookmark folder")
+
+ result =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> patch("/api/v1/pleroma/bookmark_folders/#{folder.id}", %{
+ name: "bookmark folder"
+ })
+ |> json_response_and_validate_schema(403)
+
+ assert %{
+ "error" => "Access denied"
+ } = result
+ end
+ end
+
+ describe "DELETE /api/v1/pleroma/bookmark_folders/:id" do
+ setup do: oauth_access(["write:bookmarks"])
+
+ test "it deleting a bookmark folder", %{conn: conn, user: user} do
+ {:ok, folder} = BookmarkFolder.create(user.id, "Bookmark folder")
+
+ assert conn
+ |> delete("/api/v1/pleroma/bookmark_folders/#{folder.id}")
+ |> json_response_and_validate_schema(200)
+
+ folders = BookmarkFolder.for_user(user.id)
+
+ assert length(folders) == 0
+ end
+
+ test "it returns error when deleting others' folders", %{conn: conn} do
+ other_user = insert(:user)
+
+ {:ok, folder} = BookmarkFolder.create(other_user.id, "Bookmark folder")
+
+ result =
+ conn
+ |> patch("/api/v1/pleroma/bookmark_folders/#{folder.id}")
+ |> json_response_and_validate_schema(403)
+
+ assert %{
+ "error" => "Access denied"
+ } = result
+ end
+ end
+end
diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex
index f4b6f1f9f..f656c9412 100644
--- a/test/support/http_request_mock.ex
+++ b/test/support/http_request_mock.ex
@@ -1503,6 +1503,24 @@ defmodule HttpRequestMock do
{:ok, %Tesla.Env{status: 200, body: "hello"}}
end
+ def get("https://friends.grishka.me/posts/54642", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/smithereen_non_anonymous_poll.json"),
+ headers: activitypub_object_headers()
+ }}
+ end
+
+ def get("https://friends.grishka.me/users/1", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/smithereen_user.json"),
+ headers: activitypub_object_headers()
+ }}
+ end
+
def get(url, query, body, headers) do
{:error,
"Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{inspect(headers)}"}
diff --git a/test/test_helper.exs b/test/test_helper.exs
index e65f7c1d1..a117584ae 100644
--- a/test/test_helper.exs
+++ b/test/test_helper.exs
@@ -4,6 +4,8 @@
Code.put_compiler_option(:warnings_as_errors, true)
+ExUnit.configure(max_cases: System.schedulers_online())
+
ExUnit.start(exclude: [:federated, :erratic])
if match?({:unix, :darwin}, :os.type()) do
diff --git a/uploads/.gitignore b/uploads/.gitignore
deleted file mode 100644
index 523e584a7..000000000
--- a/uploads/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-# Git will ignore everything in this directory except this file.
-*
-!.gitignore