Merge remote-tracking branch 'origin/develop' into post-languages

This commit is contained in:
marcin mikołajczak 2024-08-22 13:06:57 +02:00
commit 3e5517e7bb
655 changed files with 2268 additions and 1748 deletions

View file

@ -623,10 +623,12 @@ defmodule Mix.Tasks.Pleroma.DatabaseTest do
expires_at = DateTime.add(DateTime.utc_now(), 60 * 61)
Pleroma.Workers.PurgeExpiredActivity.enqueue(%{
activity_id: activity_id3,
expires_at: expires_at
})
Pleroma.Workers.PurgeExpiredActivity.enqueue(
%{
activity_id: activity_id3
},
scheduled_at: expires_at
)
Mix.Tasks.Pleroma.Database.run(["ensure_expiration"])

View file

@ -3,12 +3,14 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Mix.Tasks.Pleroma.UploadsTest do
alias Pleroma.Config
alias Pleroma.Upload
use Pleroma.DataCase
use Pleroma.DataCase, async: false
import Mock
setup_all do
prep_uploads()
Mix.shell(Mix.Shell.Process)
on_exit(fn ->
@ -18,6 +20,8 @@ defmodule Mix.Tasks.Pleroma.UploadsTest do
:ok
end
setup do: clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
describe "running migrate_local" do
test "uploads migrated" do
with_mock Upload,
@ -53,4 +57,15 @@ defmodule Mix.Tasks.Pleroma.UploadsTest do
end
end
end
defp prep_uploads do
upload_dir = Config.get([Pleroma.Uploaders.Local, :uploads])
if not File.exists?(upload_dir) || File.ls!(upload_dir) == [] do
File.mkdir_p(upload_dir)
Path.join([upload_dir, "file.txt"])
|> File.touch()
end
end
end

View file

@ -100,7 +100,7 @@ defmodule Pleroma.Object.FetcherTest do
test "it returns thread depth exceeded error if thread depth is exceeded" do
clear_config([:instance, :federation_incoming_replies_max_depth], 0)
assert {:error, :allowed_depth} = Fetcher.fetch_object_from_id(@ap_id, depth: 1)
assert {:allowed_depth, false} = Fetcher.fetch_object_from_id(@ap_id, depth: 1)
end
test "it fetches object if max thread depth is restricted to 0 and depth is not specified" do
@ -118,15 +118,18 @@ defmodule Pleroma.Object.FetcherTest do
describe "actor origin containment" do
test "it rejects objects with a bogus origin" do
{:error, _} = Fetcher.fetch_object_from_id("https://info.pleroma.site/activity.json")
{:containment, :error} =
Fetcher.fetch_object_from_id("https://info.pleroma.site/activity.json")
end
test "it rejects objects when attributedTo is wrong (variant 1)" do
{:error, _} = Fetcher.fetch_object_from_id("https://info.pleroma.site/activity2.json")
{:containment, :error} =
Fetcher.fetch_object_from_id("https://info.pleroma.site/activity2.json")
end
test "it rejects objects when attributedTo is wrong (variant 2)" do
{:error, _} = Fetcher.fetch_object_from_id("https://info.pleroma.site/activity3.json")
{:containment, :error} =
Fetcher.fetch_object_from_id("https://info.pleroma.site/activity3.json")
end
end
@ -150,14 +153,14 @@ defmodule Pleroma.Object.FetcherTest do
clear_config([:mrf_keyword, :reject], ["yeah"])
clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.KeywordPolicy])
assert {:reject, "[KeywordPolicy] Matches with rejected keyword"} ==
assert {:transmogrifier, {:reject, "[KeywordPolicy] Matches with rejected keyword"}} ==
Fetcher.fetch_object_from_id(
"http://mastodon.example.org/@admin/99541947525187367"
)
end
test "it does not fetch a spoofed object uploaded on an instance as an attachment" do
assert {:error, _} =
assert {:fetch, {:error, {:content_type, "application/json"}}} =
Fetcher.fetch_object_from_id(
"https://patch.cx/media/03ca3c8b4ac3ddd08bf0f84be7885f2f88de0f709112131a22d83650819e36c2.json"
)

View file

@ -0,0 +1,43 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Repo.Migrations.PublisherMigrationChangeTest do
use Oban.Testing, repo: Pleroma.Repo
use Pleroma.DataCase
import Pleroma.Factory
import Pleroma.Tests.Helpers
alias Pleroma.Activity
alias Pleroma.Workers.PublisherWorker
setup_all do: require_migration("20240729163838_publisher_job_change")
describe "up/0" do
test "migrates publisher jobs to new format", %{migration: migration} do
user = insert(:user)
%Activity{id: activity_id, data: %{"id" => ap_id}} =
insert(:note_activity, user: user)
{:ok, %{id: job_id}} =
PublisherWorker.new(%{
"actor_id" => user.id,
"json" => "{}",
"id" => ap_id,
"inbox" => "https://example.com/inbox",
"unreachable_since" => nil
})
|> Oban.insert()
assert [%{id: ^job_id, args: %{"id" => ^ap_id}}] = all_enqueued(worker: PublisherWorker)
assert migration.up() == :ok
assert_enqueued(
worker: PublisherWorker,
args: %{"id" => ap_id, "activity_id" => activity_id}
)
end
end
end

View file

@ -1,49 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.User.BackupAsyncTest do
use Pleroma.DataCase, async: true
import Pleroma.Factory
import Mox
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
alias Pleroma.User.Backup
alias Pleroma.User.Backup.ProcessorMock
setup do
user = insert(:user, %{nickname: "cofe", name: "Cofe", ap_id: "http://cofe.io/users/cofe"})
{:ok, backup} = user |> Backup.new() |> Repo.insert()
%{backup: backup}
end
test "it handles unrecoverable exceptions", %{backup: backup} do
ProcessorMock
|> expect(:do_process, fn _, _ ->
raise "mock exception"
end)
ConfigMock
|> stub_with(Pleroma.Config)
{:error, %{backup: backup, reason: :exit}} = Backup.process(backup, ProcessorMock)
assert backup.state == :failed
end
test "it handles timeouts", %{backup: backup} do
ProcessorMock
|> expect(:do_process, fn _, _ ->
Process.sleep(:timer.seconds(4))
end)
ConfigMock
|> expect(:get, fn [Pleroma.User.Backup, :process_wait_time] -> :timer.seconds(2) end)
{:error, %{backup: backup, reason: :timeout}} = Backup.process(backup, ProcessorMock)
assert backup.state == :failed
end
end

View file

@ -6,7 +6,6 @@ defmodule Pleroma.User.BackupTest do
use Oban.Testing, repo: Pleroma.Repo
use Pleroma.DataCase
import Mock
import Pleroma.Factory
import Swoosh.TestAssertions
import Mox
@ -16,7 +15,6 @@ defmodule Pleroma.User.BackupTest do
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
alias Pleroma.Uploaders.S3.ExAwsMock
alias Pleroma.User.Backup
alias Pleroma.User.Backup.ProcessorMock
alias Pleroma.Web.CommonAPI
alias Pleroma.Workers.BackupWorker
@ -28,79 +26,56 @@ defmodule Pleroma.User.BackupTest do
ConfigMock
|> stub_with(Pleroma.Config)
ProcessorMock
|> stub_with(Pleroma.User.Backup.Processor)
:ok
end
test "it does not requrie enabled email" do
clear_config([Pleroma.Emails.Mailer, :enabled], false)
user = insert(:user)
assert {:ok, _} = Backup.create(user)
assert {:ok, _} = Backup.user(user)
end
test "it does not require user's email" do
user = insert(:user, %{email: nil})
assert {:ok, _} = Backup.create(user)
assert {:ok, _} = Backup.user(user)
end
test "it creates a backup record and an Oban job" do
%{id: user_id} = user = insert(:user)
assert {:ok, %Oban.Job{args: args}} = Backup.create(user)
user = insert(:user)
assert {:ok, %Backup{} = backup} = Backup.user(user)
assert {:ok, %Oban.Job{args: args}} = Backup.schedule_backup(backup)
assert_enqueued(worker: BackupWorker, args: args)
backup = Backup.get(args["backup_id"])
assert %Backup{user_id: ^user_id, processed: false, file_size: 0, state: :pending} = backup
backup = Backup.get_by_id(args["backup_id"])
assert %Backup{processed: false, file_size: 0} = backup
end
test "it return an error if the export limit is over" do
%{id: user_id} = user = insert(:user)
user = insert(:user)
limit_days = Pleroma.Config.get([Backup, :limit_days])
assert {:ok, %Oban.Job{args: args}} = Backup.create(user)
backup = Backup.get(args["backup_id"])
assert %Backup{user_id: ^user_id, processed: false, file_size: 0} = backup
{:ok, first_backup} = Backup.user(user)
{:ok, _run_backup} = Backup.run(first_backup)
assert Backup.create(user) == {:error, "Last export was less than #{limit_days} days ago"}
assert Backup.user(user) == {:error, "Last export was less than #{limit_days} days ago"}
end
test "it process a backup record" do
clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
%{id: user_id} = user = insert(:user)
assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id} = args}} = Backup.create(user)
assert {:ok, backup} = perform_job(BackupWorker, args)
assert {:ok, %Backup{id: backup_id}} = Backup.user(user)
oban_args = %{"op" => "process", "backup_id" => backup_id}
assert {:ok, backup} = perform_job(BackupWorker, oban_args)
assert backup.file_size > 0
assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id, state: :complete} = backup
assert match?(%Backup{id: ^backup_id, processed: true, user_id: ^user_id}, backup)
delete_job_args = %{"op" => "delete", "backup_id" => backup_id}
assert_enqueued(worker: BackupWorker, args: delete_job_args)
assert {:ok, backup} = perform_job(BackupWorker, delete_job_args)
refute Backup.get(backup_id)
email = Pleroma.Emails.UserEmail.backup_is_ready_email(backup)
assert_email_sent(
to: {user.name, user.email},
html_body: email.html_body
)
end
test "it updates states of the backup" do
clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
%{id: user_id} = user = insert(:user)
assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id} = args}} = Backup.create(user)
assert {:ok, backup} = perform_job(BackupWorker, args)
assert backup.file_size > 0
assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id, state: :complete} = backup
delete_job_args = %{"op" => "delete", "backup_id" => backup_id}
assert_enqueued(worker: BackupWorker, args: delete_job_args)
assert {:ok, backup} = perform_job(BackupWorker, delete_job_args)
refute Backup.get(backup_id)
refute Backup.get_by_id(backup_id)
email = Pleroma.Emails.UserEmail.backup_is_ready_email(backup)
@ -114,10 +89,15 @@ defmodule Pleroma.User.BackupTest do
clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
%{id: user_id} = user = insert(:user, %{email: nil})
assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id} = args}} = Backup.create(user)
assert {:ok, backup} = perform_job(BackupWorker, args)
assert backup.file_size > 0
assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id} = backup
assert {:ok, %Backup{} = backup} = Backup.user(user)
expected_args = %{"op" => "process", "backup_id" => backup.id}
assert_enqueued(worker: BackupWorker, args: %{"backup_id" => backup.id})
assert {:ok, completed_backup} = perform_job(BackupWorker, expected_args)
assert completed_backup.file_size > 0
assert completed_backup.processed
assert completed_backup.user_id == user_id
assert_no_email_sent()
end
@ -127,10 +107,13 @@ defmodule Pleroma.User.BackupTest do
clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
%{id: user_id} = user = insert(:user)
assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id} = args}} = Backup.create(user)
assert {:ok, backup} = perform_job(BackupWorker, args)
assert {:ok, %Backup{id: backup_id}} = Backup.user(user)
oban_args = %{"op" => "process", "backup_id" => backup_id}
assert {:ok, backup} = perform_job(BackupWorker, oban_args)
assert backup.file_size > 0
assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id} = backup
assert match?(%Backup{id: ^backup_id, processed: true, user_id: ^user_id}, backup)
assert_no_email_sent()
end
@ -139,10 +122,15 @@ defmodule Pleroma.User.BackupTest do
clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
%{id: user_id} = user = insert(:user, %{email: ""})
assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id} = args}} = Backup.create(user)
assert {:ok, backup} = perform_job(BackupWorker, args)
assert {:ok, %Backup{id: backup_id} = backup} = Backup.user(user)
expected_args = %{"op" => "process", "backup_id" => backup.id}
assert_enqueued(worker: BackupWorker, args: expected_args)
assert {:ok, backup} = perform_job(BackupWorker, expected_args)
assert backup.file_size > 0
assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id} = backup
assert match?(%Backup{id: ^backup_id, processed: true, user_id: ^user_id}, backup)
assert_no_email_sent()
end
@ -152,16 +140,13 @@ defmodule Pleroma.User.BackupTest do
clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
user = insert(:user)
assert {:ok, job1} = Backup.create(user)
assert {:ok, %Backup{}} = ObanHelpers.perform(job1)
assert {:ok, job2} = Backup.create(user)
assert Pleroma.Repo.aggregate(Backup, :count) == 2
assert {:ok, backup2} = ObanHelpers.perform(job2)
assert {:ok, %{id: backup_one_id}} = Backup.user(user)
assert {:ok, %{id: _backup_two_id}} = Backup.user(user)
# Run the backups
ObanHelpers.perform_all()
assert [^backup2] = Pleroma.Repo.all(Backup)
assert_enqueued(worker: BackupWorker, args: %{"op" => "delete", "backup_id" => backup_one_id})
end
test "it creates a zip archive with user data" do
@ -185,9 +170,12 @@ defmodule Pleroma.User.BackupTest do
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, backup} = Backup.user(user)
assert {:ok, run_backup} = Backup.run(backup)
tempfile = Path.join([run_backup.tempdir, run_backup.file_name])
assert {:ok, zipfile} = :zip.zip_open(String.to_charlist(tempfile), [:memory])
assert {:ok, {~c"actor.json", json}} = :zip.zip_get(~c"actor.json", zipfile)
assert %{
@ -275,10 +263,10 @@ defmodule Pleroma.User.BackupTest do
} = Jason.decode!(json)
:zip.zip_close(zipfile)
File.rm!(path)
File.rm_rf!(run_backup.tempdir)
end
test "it counts the correct number processed" do
test "correct number processed" do
user = insert(:user, %{nickname: "cofe", name: "Cofe", ap_id: "http://cofe.io/users/cofe"})
Enum.map(1..120, fn i ->
@ -288,43 +276,21 @@ defmodule Pleroma.User.BackupTest do
end)
assert {:ok, backup} = user |> Backup.new() |> Repo.insert()
{:ok, backup} = Backup.process(backup)
{:ok, backup} = Backup.run(backup)
assert backup.processed_number == 1 + 120 + 120 + 120
zip_path = Path.join([backup.tempdir, backup.file_name])
Backup.delete(backup)
end
assert {:ok, zipfile} = :zip.zip_open(String.to_charlist(zip_path), [:memory])
test "it handles errors" do
user = insert(:user, %{nickname: "cofe", name: "Cofe", ap_id: "http://cofe.io/users/cofe"})
backup_parts = [~c"likes.json", ~c"bookmarks.json", ~c"outbox.json"]
Enum.map(1..120, fn i ->
{:ok, _status} = CommonAPI.post(user, %{status: "status #{i}"})
Enum.each(backup_parts, fn part ->
assert {:ok, {_part, part_json}} = :zip.zip_get(part, zipfile)
{:ok, decoded_part} = Jason.decode(part_json)
assert decoded_part["totalItems"] == 120
end)
assert {:ok, backup} = user |> Backup.new() |> Repo.insert()
with_mock Pleroma.Web.ActivityPub.Transmogrifier,
[:passthrough],
prepare_outgoing: fn data ->
object =
data["object"]
|> Pleroma.Object.normalize(fetch: false)
|> Map.get(:data)
data = data |> Map.put("object", object)
if String.contains?(data["object"]["content"], "119"),
do: raise(%Postgrex.Error{}),
else: {:ok, data}
end do
{:ok, backup} = Backup.process(backup)
assert backup.processed
assert backup.state == :complete
assert backup.processed_number == 1 + 119
Backup.delete(backup)
end
Backup.delete_archive(backup)
end
describe "it uploads and deletes a backup archive" do
@ -343,12 +309,11 @@ defmodule Pleroma.User.BackupTest do
Bookmark.create(user.id, status3.id)
assert {:ok, backup} = user |> Backup.new() |> Repo.insert()
assert {:ok, path} = Backup.export(backup, self())
[path: path, backup: backup]
[backup: backup]
end
test "S3", %{path: path, backup: backup} do
test "S3", %{backup: backup} do
clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.S3)
clear_config([Pleroma.Uploaders.S3, :streaming_enabled], false)
@ -358,15 +323,17 @@ defmodule Pleroma.User.BackupTest do
%{http_method: :delete} -> {:ok, %{status_code: 204}}
end)
assert {:ok, %Pleroma.Upload{}} = Backup.upload(backup, path)
assert {:ok, _backup} = Backup.delete(backup)
assert {:ok, backup} = Backup.run(backup)
assert {:ok, %Backup{processed: true}} = Backup.upload(backup)
assert {:ok, _backup} = Backup.delete_archive(backup)
end
test "Local", %{path: path, backup: backup} do
test "Local", %{backup: backup} do
clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
assert {:ok, %Pleroma.Upload{}} = Backup.upload(backup, path)
assert {:ok, _backup} = Backup.delete(backup)
assert {:ok, backup} = Backup.run(backup)
assert {:ok, %Backup{processed: true}} = Backup.upload(backup)
assert {:ok, _backup} = Backup.delete_archive(backup)
end
end
end

View file

@ -1075,6 +1075,21 @@ defmodule Pleroma.UserTest do
refute cs.valid?
end
test "it truncates fields" do
clear_config([:instance, :max_remote_account_fields], 2)
fields = [
%{"name" => "One", "value" => "Uno"},
%{"name" => "Two", "value" => "Dos"},
%{"name" => "Three", "value" => "Tres"}
]
cs = User.remote_user_changeset(@valid_remote |> Map.put(:fields, fields))
assert [%{"name" => "One", "value" => "Uno"}, %{"name" => "Two", "value" => "Dos"}] ==
Ecto.Changeset.get_field(cs, :fields)
end
end
describe "followers and friends" do

View file

@ -1747,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(user, other_user)
{:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)
result =
conn
@ -1843,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(other_user, user)
{:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
result =
conn

View file

@ -0,0 +1,117 @@
# 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.FODirectReplyTest do
use Pleroma.DataCase
import Pleroma.Factory
require Pleroma.Constants
alias Pleroma.Object
alias Pleroma.Web.ActivityPub.MRF.FODirectReply
alias Pleroma.Web.CommonAPI
test "replying to followers-only/private is changed to direct" do
batman = insert(:user, nickname: "batman")
robin = insert(:user, nickname: "robin")
{:ok, post} =
CommonAPI.post(batman, %{
status: "Has anyone seen Selina Kyle's latest selfies?",
visibility: "private"
})
reply = %{
"type" => "Create",
"actor" => robin.ap_id,
"to" => [batman.ap_id, robin.follower_address],
"cc" => [],
"object" => %{
"type" => "Note",
"actor" => robin.ap_id,
"content" => "@batman 🤤 ❤️ 🐈‍⬛",
"to" => [batman.ap_id, robin.follower_address],
"cc" => [],
"inReplyTo" => Object.normalize(post).data["id"]
}
}
expected_to = [batman.ap_id]
expected_cc = []
assert {:ok, filtered} = FODirectReply.filter(reply)
assert expected_to == filtered["to"]
assert expected_cc == filtered["cc"]
assert expected_to == filtered["object"]["to"]
assert expected_cc == filtered["object"]["cc"]
end
test "replies to unlisted posts are unmodified" do
batman = insert(:user, nickname: "batman")
robin = insert(:user, nickname: "robin")
{:ok, post} =
CommonAPI.post(batman, %{
status: "Has anyone seen Selina Kyle's latest selfies?",
visibility: "unlisted"
})
reply = %{
"type" => "Create",
"actor" => robin.ap_id,
"to" => [batman.ap_id, robin.follower_address],
"cc" => [],
"object" => %{
"type" => "Note",
"actor" => robin.ap_id,
"content" => "@batman 🤤 ❤️ 🐈<200d>⬛",
"to" => [batman.ap_id, robin.follower_address],
"cc" => [],
"inReplyTo" => Object.normalize(post).data["id"]
}
}
assert {:ok, filtered} = FODirectReply.filter(reply)
assert match?(^filtered, reply)
end
test "replies to public posts are unmodified" do
batman = insert(:user, nickname: "batman")
robin = insert(:user, nickname: "robin")
{:ok, post} =
CommonAPI.post(batman, %{status: "Has anyone seen Selina Kyle's latest selfies?"})
reply = %{
"type" => "Create",
"actor" => robin.ap_id,
"to" => [batman.ap_id, robin.follower_address],
"cc" => [],
"object" => %{
"type" => "Note",
"actor" => robin.ap_id,
"content" => "@batman 🤤 ❤️ 🐈<200d>⬛",
"to" => [batman.ap_id, robin.follower_address],
"cc" => [],
"inReplyTo" => Object.normalize(post).data["id"]
}
}
assert {:ok, filtered} = FODirectReply.filter(reply)
assert match?(^filtered, reply)
end
test "non-reply posts are unmodified" do
batman = insert(:user, nickname: "batman")
{:ok, post} = CommonAPI.post(batman, %{status: "To the Batmobile!"})
assert {:ok, filtered} = FODirectReply.filter(post)
assert match?(^filtered, post)
end
end

View file

@ -0,0 +1,140 @@
# 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.QuietReplyTest do
use Pleroma.DataCase
import Pleroma.Factory
require Pleroma.Constants
alias Pleroma.Object
alias Pleroma.Web.ActivityPub.MRF.QuietReply
alias Pleroma.Web.CommonAPI
test "replying to public post is forced to be quiet" do
batman = insert(:user, nickname: "batman")
robin = insert(:user, nickname: "robin")
{:ok, post} = CommonAPI.post(batman, %{status: "To the Batmobile!"})
reply = %{
"type" => "Create",
"actor" => robin.ap_id,
"to" => [
batman.ap_id,
Pleroma.Constants.as_public()
],
"cc" => [robin.follower_address],
"object" => %{
"type" => "Note",
"actor" => robin.ap_id,
"content" => "@batman Wait up, I forgot my spandex!",
"to" => [
batman.ap_id,
Pleroma.Constants.as_public()
],
"cc" => [robin.follower_address],
"inReplyTo" => Object.normalize(post).data["id"]
}
}
expected_to = [batman.ap_id, robin.follower_address]
expected_cc = [Pleroma.Constants.as_public()]
assert {:ok, filtered} = QuietReply.filter(reply)
assert expected_to == filtered["to"]
assert expected_cc == filtered["cc"]
assert expected_to == filtered["object"]["to"]
assert expected_cc == filtered["object"]["cc"]
end
test "replying to unlisted post is unmodified" do
batman = insert(:user, nickname: "batman")
robin = insert(:user, nickname: "robin")
{:ok, post} = CommonAPI.post(batman, %{status: "To the Batmobile!", visibility: "private"})
reply = %{
"type" => "Create",
"actor" => robin.ap_id,
"to" => [batman.ap_id],
"cc" => [],
"object" => %{
"type" => "Note",
"actor" => robin.ap_id,
"content" => "@batman Wait up, I forgot my spandex!",
"to" => [batman.ap_id],
"cc" => [],
"inReplyTo" => Object.normalize(post).data["id"]
}
}
assert {:ok, filtered} = QuietReply.filter(reply)
assert match?(^filtered, reply)
end
test "replying direct is unmodified" do
batman = insert(:user, nickname: "batman")
robin = insert(:user, nickname: "robin")
{:ok, post} = CommonAPI.post(batman, %{status: "To the Batmobile!"})
reply = %{
"type" => "Create",
"actor" => robin.ap_id,
"to" => [batman.ap_id],
"cc" => [],
"object" => %{
"type" => "Note",
"actor" => robin.ap_id,
"content" => "@batman Wait up, I forgot my spandex!",
"to" => [batman.ap_id],
"cc" => [],
"inReplyTo" => Object.normalize(post).data["id"]
}
}
assert {:ok, filtered} = QuietReply.filter(reply)
assert match?(^filtered, reply)
end
test "replying followers-only is unmodified" do
batman = insert(:user, nickname: "batman")
robin = insert(:user, nickname: "robin")
{:ok, post} = CommonAPI.post(batman, %{status: "To the Batmobile!"})
reply = %{
"type" => "Create",
"actor" => robin.ap_id,
"to" => [batman.ap_id, robin.follower_address],
"cc" => [],
"object" => %{
"type" => "Note",
"actor" => robin.ap_id,
"content" => "@batman Wait up, I forgot my spandex!",
"to" => [batman.ap_id, robin.follower_address],
"cc" => [],
"inReplyTo" => Object.normalize(post).data["id"]
}
}
assert {:ok, filtered} = QuietReply.filter(reply)
assert match?(^filtered, reply)
end
test "non-reply posts are unmodified" do
batman = insert(:user, nickname: "batman")
{:ok, post} = CommonAPI.post(batman, %{status: "To the Batmobile!"})
assert {:ok, filtered} = QuietReply.filter(post)
assert match?(^filtered, post)
end
end

View file

@ -22,5 +22,15 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.FollowValidationTest do
test "validates a basic follow object", %{valid_follow: valid_follow} do
assert {:ok, _follow, []} = ObjectValidator.validate(valid_follow, [])
end
test "supports a nil cc", %{valid_follow: valid_follow} do
valid_follow_with_nil_cc = Map.put(valid_follow, "cc", nil)
assert {:ok, _follow, []} = ObjectValidator.validate(valid_follow_with_nil_cc, [])
end
test "supports an empty cc", %{valid_follow: valid_follow} do
valid_follow_with_empty_cc = Map.put(valid_follow, "cc", [])
assert {:ok, _follow, []} = ObjectValidator.validate(valid_follow_with_empty_cc, [])
end
end
end

View file

@ -3,6 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.PublisherTest do
use Oban.Testing, repo: Pleroma.Repo
use Pleroma.Web.ConnCase
import ExUnit.CaptureLog
@ -13,6 +14,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
alias Pleroma.Activity
alias Pleroma.Instances
alias Pleroma.Object
alias Pleroma.Tests.ObanHelpers
alias Pleroma.Web.ActivityPub.Publisher
alias Pleroma.Web.CommonAPI
@ -137,6 +139,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
test "publish to url with with different ports" do
inbox80 = "http://42.site/users/nick1/inbox"
inbox42 = "http://42.site:42/users/nick1/inbox"
activity = insert(:note_activity)
mock(fn
%{method: :post, url: "http://42.site:42/users/nick1/inbox"} ->
@ -146,53 +149,40 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
{:ok, %Tesla.Env{status: 200, body: "port 80"}}
end)
actor = insert(:user)
_actor = insert(:user)
assert {:ok, %{body: "port 42"}} =
Publisher.publish_one(%{
Publisher.prepare_one(%{
inbox: inbox42,
json: "{}",
actor: actor,
id: 1,
activity_id: activity.id,
unreachable_since: true
})
|> Publisher.publish_one()
assert {:ok, %{body: "port 80"}} =
Publisher.publish_one(%{
Publisher.prepare_one(%{
inbox: inbox80,
json: "{}",
actor: actor,
id: 1,
activity_id: activity.id,
unreachable_since: true
})
end
test_with_mock "calls `Instances.set_reachable` on successful federation if `unreachable_since` is not specified",
Instances,
[:passthrough],
[] do
actor = insert(:user)
inbox = "http://200.site/users/nick1/inbox"
assert {:ok, _} = Publisher.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1})
assert called(Instances.set_reachable(inbox))
|> Publisher.publish_one()
end
test_with_mock "calls `Instances.set_reachable` on successful federation if `unreachable_since` is set",
Instances,
[:passthrough],
[] do
actor = insert(:user)
_actor = insert(:user)
inbox = "http://200.site/users/nick1/inbox"
activity = insert(:note_activity)
assert {:ok, _} =
Publisher.publish_one(%{
Publisher.prepare_one(%{
inbox: inbox,
json: "{}",
actor: actor,
id: 1,
unreachable_since: NaiveDateTime.utc_now()
activity_id: activity.id,
unreachable_since: NaiveDateTime.utc_now() |> NaiveDateTime.to_string()
})
|> Publisher.publish_one()
assert called(Instances.set_reachable(inbox))
end
@ -201,17 +191,17 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
Instances,
[:passthrough],
[] do
actor = insert(:user)
_actor = insert(:user)
inbox = "http://200.site/users/nick1/inbox"
activity = insert(:note_activity)
assert {:ok, _} =
Publisher.publish_one(%{
Publisher.prepare_one(%{
inbox: inbox,
json: "{}",
actor: actor,
id: 1,
activity_id: activity.id,
unreachable_since: nil
})
|> Publisher.publish_one()
refute called(Instances.set_reachable(inbox))
end
@ -220,11 +210,13 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
Instances,
[:passthrough],
[] do
actor = insert(:user)
_actor = insert(:user)
inbox = "http://404.site/users/nick1/inbox"
activity = insert(:note_activity)
assert {:cancel, _} =
Publisher.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1})
Publisher.prepare_one(%{inbox: inbox, activity_id: activity.id})
|> Publisher.publish_one()
assert called(Instances.set_unreachable(inbox))
end
@ -233,12 +225,17 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
Instances,
[:passthrough],
[] do
actor = insert(:user)
_actor = insert(:user)
inbox = "http://connrefused.site/users/nick1/inbox"
activity = insert(:note_activity)
assert capture_log(fn ->
assert {:error, _} =
Publisher.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1})
Publisher.prepare_one(%{
inbox: inbox,
activity_id: activity.id
})
|> Publisher.publish_one()
end) =~ "connrefused"
assert called(Instances.set_unreachable(inbox))
@ -248,10 +245,13 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
Instances,
[:passthrough],
[] do
actor = insert(:user)
_actor = insert(:user)
inbox = "http://200.site/users/nick1/inbox"
activity = insert(:note_activity)
assert {:ok, _} = Publisher.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1})
assert {:ok, _} =
Publisher.prepare_one(%{inbox: inbox, activity_id: activity.id})
|> Publisher.publish_one()
refute called(Instances.set_unreachable(inbox))
end
@ -260,18 +260,18 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
Instances,
[:passthrough],
[] do
actor = insert(:user)
_actor = insert(:user)
inbox = "http://connrefused.site/users/nick1/inbox"
activity = insert(:note_activity)
assert capture_log(fn ->
assert {:error, _} =
Publisher.publish_one(%{
Publisher.prepare_one(%{
inbox: inbox,
json: "{}",
actor: actor,
id: 1,
unreachable_since: NaiveDateTime.utc_now()
activity_id: activity.id,
unreachable_since: NaiveDateTime.utc_now() |> NaiveDateTime.to_string()
})
|> Publisher.publish_one()
end) =~ "connrefused"
refute called(Instances.set_unreachable(inbox))
@ -306,13 +306,15 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
assert res == :ok
assert not called(
Publisher.enqueue_one(%{
inbox: "https://domain.com/users/nick1/inbox",
actor_id: actor.id,
id: note_activity.data["id"]
})
)
refute_enqueued(
worker: "Pleroma.Workers.PublisherWorker",
args: %{
"params" => %{
inbox: "https://domain.com/users/nick1/inbox",
activity_id: note_activity.id
}
}
)
end
test_with_mock "Publishes a non-public activity to non-quarantined instances.",
@ -342,16 +344,16 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
assert res == :ok
assert called(
Publisher.enqueue_one(
%{
inbox: "https://domain.com/users/nick1/inbox",
actor_id: actor.id,
id: note_activity.data["id"]
},
priority: 1
)
)
assert_enqueued(
worker: "Pleroma.Workers.PublisherWorker",
args: %{
"params" => %{
inbox: "https://domain.com/users/nick1/inbox",
activity_id: note_activity.id
}
},
priority: 1
)
end
test_with_mock "Publishes to directly addressed actors with higher priority.",
@ -370,8 +372,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
Publisher.enqueue_one(
%{
inbox: :_,
actor_id: actor.id,
id: note_activity.data["id"]
activity_id: note_activity.id
},
priority: 0
)
@ -402,13 +403,15 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
res = Publisher.publish(actor, note_activity)
assert res == :ok
assert called(
Publisher.enqueue_one(%{
inbox: "https://domain.com/users/nick1/inbox",
actor_id: actor.id,
id: note_activity.data["id"]
})
)
assert_enqueued(
worker: "Pleroma.Workers.PublisherWorker",
args: %{
"params" => %{
inbox: "https://domain.com/users/nick1/inbox",
activity_id: note_activity.id
}
}
)
end
test_with_mock "publishes a delete activity to peers who signed fetch requests to the create acitvity/object.",
@ -452,27 +455,69 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
res = Publisher.publish(actor, delete)
assert res == :ok
assert called(
Publisher.enqueue_one(
%{
inbox: "https://domain.com/users/nick1/inbox",
actor_id: actor.id,
id: delete.data["id"]
},
priority: 1
)
)
assert_enqueued(
worker: "Pleroma.Workers.PublisherWorker",
args: %{
"params" => %{
inbox: "https://domain.com/users/nick1/inbox",
activity_id: delete.id
}
},
priority: 1
)
assert called(
Publisher.enqueue_one(
%{
inbox: "https://domain2.com/users/nick1/inbox",
actor_id: actor.id,
id: delete.data["id"]
},
priority: 1
)
)
assert_enqueued(
worker: "Pleroma.Workers.PublisherWorker",
args: %{
"params" => %{
inbox: "https://domain2.com/users/nick1/inbox",
activity_id: delete.id
}
},
priority: 1
)
end
end
test "cc in prepared json for a follow request is an empty list" do
user = insert(:user)
remote_user = insert(:user, local: false)
{:ok, _, _, activity} = CommonAPI.follow(remote_user, user)
assert_enqueued(
worker: "Pleroma.Workers.PublisherWorker",
args: %{
"activity_id" => activity.id,
"op" => "publish"
}
)
ObanHelpers.perform_all()
expected_params =
%{
"activity_id" => activity.id,
"inbox" => remote_user.inbox,
"unreachable_since" => nil
}
assert_enqueued(
worker: "Pleroma.Workers.PublisherWorker",
args: %{
"op" => "publish_one",
"params" => expected_params
}
)
# params need to be atom keys for Publisher.prepare_one.
# this is done in the Oban job.
expected_params = Map.new(expected_params, fn {k, v} -> {String.to_atom(k), v} end)
%{json: json} = Publisher.prepare_one(expected_params)
{:ok, decoded} = Jason.decode(json)
assert decoded["cc"] == []
end
end

View file

@ -54,20 +54,17 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
[
stream: fn _, _ -> nil end
]
},
{
Pleroma.Web.Push,
[],
[
send: fn _ -> nil end
]
}
]) do
SideEffects.handle_after_transaction(meta)
assert called(Pleroma.Web.Streamer.stream(["user", "user:notification"], notification))
assert called(Pleroma.Web.Streamer.stream(["user", "user:pleroma_chat"], :_))
assert called(Pleroma.Web.Push.send(notification))
assert_enqueued(
worker: "Pleroma.Workers.WebPusherWorker",
args: %{"notification_id" => notification.id, "op" => "web_push"}
)
end
end
end

View file

@ -119,8 +119,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.UserUpdateHandlingTest do
user = User.get_cached_by_ap_id(user.ap_id)
assert user.fields == [
%{"name" => "foo", "value" => "updated"},
%{"name" => "foo1", "value" => "updated"}
%{"name" => "foo", "value" => "bar"},
%{"name" => "foo11", "value" => "bar11"}
]
update_data =

View file

@ -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(user, other_user)
{:ok, user, _other_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(user, other_user)
{:ok, user, _other_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(other_user, user)
{:ok, _other_user, 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(other_user, user)
{:ok, _other_user, 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})

View file

@ -1096,9 +1096,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
ObanHelpers.perform_all()
email = Pleroma.Emails.UserEmail.backup_is_ready_email(backup, admin.id)
email = Pleroma.Emails.UserEmail.backup_is_ready_email(backup)
assert String.contains?(
email.html_body,
"A full backup of your Pleroma account was requested"
)
assert String.contains?(email.html_body, "Admin @#{admin.nickname} requested a full backup")
assert_email_sent(to: {user.name, user.email}, html_body: email.html_body)
log_message = "@#{admin_nickname} requested account backup for @#{user_nickname}"

View file

@ -1420,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(followed, follower)
{:ok, followed, follower, _} = CommonAPI.follow(followed, follower)
assert User.following?(follower, followed)
end
@ -1429,7 +1429,7 @@ 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(followed, follower)
{:ok, followed, follower, _} = CommonAPI.follow(followed, follower)
{:ok, _subscription} = User.subscribe(follower, followed)
assert User.subscribed_to?(follower, followed)
@ -1441,7 +1441,7 @@ defmodule Pleroma.Web.CommonAPITest do
test "also unpins a user" do
[follower, followed] = insert_pair(:user)
{:ok, follower, followed, _} = CommonAPI.follow(followed, follower)
{:ok, followed, follower, _} = CommonAPI.follow(followed, follower)
{:ok, _endorsement} = User.endorse(follower, followed)
assert User.endorses?(follower, followed)
@ -1455,7 +1455,7 @@ defmodule Pleroma.Web.CommonAPITest do
follower = insert(:user)
followed = insert(:user, is_locked: true)
assert {:ok, follower, followed, %{id: activity_id, data: %{"state" => "pending"}}} =
assert {:ok, followed, follower, %{id: activity_id, data: %{"state" => "pending"}}} =
CommonAPI.follow(followed, follower)
assert User.get_follow_state(follower, followed) == :follow_pending
@ -1477,7 +1477,7 @@ defmodule Pleroma.Web.CommonAPITest do
follower = insert(:user)
followed = insert(:user, is_locked: true, local: false)
assert {:ok, follower, followed, %{id: activity_id, data: %{"state" => "pending"}}} =
assert {:ok, followed, follower, %{id: activity_id, data: %{"state" => "pending"}}} =
CommonAPI.follow(followed, follower)
assert User.get_follow_state(follower, followed) == :follow_pending
@ -1957,7 +1957,7 @@ defmodule Pleroma.Web.CommonAPITest do
{:ok, _, _} = Pleroma.User.follow(remote_one, local_user)
{:ok, _, _} = Pleroma.User.follow(remote_two, local_user)
{:ok, %{data: %{"id" => ap_id}} = activity} =
{:ok, %{id: activity_id} = _activity} =
CommonAPI.post(local_user, %{status: "Happy Friday everyone!"})
# Generate the publish_one jobs
@ -1971,7 +1971,7 @@ defmodule Pleroma.Web.CommonAPITest do
state: "available",
queue: "federator_outgoing",
worker: "Pleroma.Workers.PublisherWorker",
args: %{"op" => "publish_one", "params" => %{"id" => ^ap_id}}
args: %{"op" => "publish_one", "params" => %{"activity_id" => ^activity_id}}
},
job
)
@ -1980,7 +1980,7 @@ defmodule Pleroma.Web.CommonAPITest do
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)
assert {:ok, _delete} = CommonAPI.delete(activity_id, local_user)
# all_enqueued/1 will not return cancelled jobs
cancelled_jobs =
@ -1988,7 +1988,7 @@ defmodule Pleroma.Web.CommonAPITest do
|> 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)
|> where([j], j.args["params"]["activity_id"] == ^activity_id)
|> Pleroma.Repo.all()
assert length(cancelled_jobs) == 2
@ -2001,7 +2001,7 @@ defmodule Pleroma.Web.CommonAPITest do
{:ok, activity} =
CommonAPI.post(remote_user, %{status: "I like turtles!"})
{:ok, %{data: %{"id" => ap_id}} = _favorite} =
{:ok, %{id: favorite_id} = _favorite} =
CommonAPI.favorite(activity.id, local_user)
# Generate the publish_one jobs
@ -2015,7 +2015,7 @@ defmodule Pleroma.Web.CommonAPITest do
state: "available",
queue: "federator_outgoing",
worker: "Pleroma.Workers.PublisherWorker",
args: %{"op" => "publish_one", "params" => %{"id" => ^ap_id}}
args: %{"op" => "publish_one", "params" => %{"activity_id" => ^favorite_id}}
},
job
)
@ -2032,7 +2032,7 @@ defmodule Pleroma.Web.CommonAPITest do
|> 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)
|> where([j], j.args["params"]["activity_id"] == ^favorite_id)
|> Pleroma.Repo.all()
assert length(cancelled_jobs) == 1
@ -2049,7 +2049,7 @@ defmodule Pleroma.Web.CommonAPITest do
{:ok, activity} =
CommonAPI.post(remote_one, %{status: "This is an unpleasant post"})
{:ok, %{data: %{"id" => ap_id}} = _repeat} =
{:ok, %{id: repeat_id} = _repeat} =
CommonAPI.repeat(activity.id, local_user)
# Generate the publish_one jobs
@ -2063,7 +2063,7 @@ defmodule Pleroma.Web.CommonAPITest do
state: "available",
queue: "federator_outgoing",
worker: "Pleroma.Workers.PublisherWorker",
args: %{"op" => "publish_one", "params" => %{"id" => ^ap_id}}
args: %{"op" => "publish_one", "params" => %{"activity_id" => ^repeat_id}}
},
job
)
@ -2080,7 +2080,7 @@ defmodule Pleroma.Web.CommonAPITest do
|> 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)
|> where([j], j.args["params"]["activity_id"] == ^repeat_id)
|> Pleroma.Repo.all()
assert length(cancelled_jobs) == 2
@ -2094,11 +2094,11 @@ defmodule Pleroma.Web.CommonAPITest do
{:ok, _, _} = Pleroma.User.follow(remote_one, local_user)
{:ok, _, _} = Pleroma.User.follow(remote_two, local_user)
{:ok, activity} =
{:ok, %{id: activity_id}} =
CommonAPI.post(remote_one, %{status: "Gang gang!!!!"})
{:ok, %{data: %{"id" => ap_id}} = _react} =
CommonAPI.react_with_emoji(activity.id, local_user, "👍")
{:ok, %{id: react_id} = _react} =
CommonAPI.react_with_emoji(activity_id, local_user, "👍")
# Generate the publish_one jobs
ObanHelpers.perform_all()
@ -2111,7 +2111,7 @@ defmodule Pleroma.Web.CommonAPITest do
state: "available",
queue: "federator_outgoing",
worker: "Pleroma.Workers.PublisherWorker",
args: %{"op" => "publish_one", "params" => %{"id" => ^ap_id}}
args: %{"op" => "publish_one", "params" => %{"activity_id" => ^react_id}}
},
job
)
@ -2120,7 +2120,7 @@ defmodule Pleroma.Web.CommonAPITest do
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, "👍")
assert {:ok, _unreact} = CommonAPI.unreact_with_emoji(activity_id, local_user, "👍")
# all_enqueued/1 will not return cancelled jobs
cancelled_jobs =
@ -2128,7 +2128,7 @@ defmodule Pleroma.Web.CommonAPITest do
|> 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)
|> where([j], j.args["params"]["activity_id"] == ^react_id)
|> Pleroma.Repo.all()
assert length(cancelled_jobs) == 2

View file

@ -5,6 +5,10 @@
defmodule Pleroma.Web.MastodonAPI.MarkerControllerTest do
use Pleroma.Web.ConnCase, async: true
alias Pleroma.Notification
alias Pleroma.Repo
alias Pleroma.Web.CommonAPI
import Pleroma.Factory
describe "GET /api/v1/markers" do
@ -127,5 +131,36 @@ defmodule Pleroma.Web.MastodonAPI.MarkerControllerTest do
assert response == %{"error" => "Insufficient permissions: write:statuses."}
end
test "marks notifications as read", %{conn: conn} do
user1 = insert(:user)
token = insert(:oauth_token, user: user1, scopes: ["write:statuses"])
user2 = insert(:user)
{:ok, _activity1} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"})
{:ok, _activity2} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"})
{:ok, _activity3} = CommonAPI.post(user2, %{status: "HIE @#{user1.nickname}"})
[notification3, notification2, notification1] = Notification.for_user(user1, %{limit: 3})
refute Repo.get(Notification, notification1.id).seen
refute Repo.get(Notification, notification2.id).seen
refute Repo.get(Notification, notification3.id).seen
conn
|> assign(:user, user1)
|> assign(:token, token)
|> put_req_header("content-type", "application/json")
|> post("/api/v1/markers", %{
notifications: %{last_read_id: to_string(notification2.id)}
})
|> json_response_and_validate_schema(200)
[notification3, notification2, notification1] = Notification.for_user(user1, %{limit: 3})
assert Repo.get(Notification, notification1.id).seen
assert Repo.get(Notification, notification2.id).seen
refute Repo.get(Notification, notification3.id).seen
end
end
end

View file

@ -922,13 +922,23 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
%{id: id1} = insert(:note_activity)
%{id: id2} = insert(:note_activity)
query_string = "ids[]=#{id1}&ids[]=#{id2}"
query_string = "id[]=#{id1}&id[]=#{id2}"
conn = get(conn, "/api/v1/statuses/?#{query_string}")
assert [%{"id" => ^id1}, %{"id" => ^id2}] =
Enum.sort_by(json_response_and_validate_schema(conn, :ok), & &1["id"])
end
test "get statuses by IDs falls back to ids[]" do
%{conn: conn} = oauth_access(["read:statuses"])
%{id: id} = insert(:note_activity)
query_string = "ids[]=#{id}"
conn = get(conn, "/api/v1/statuses/?#{query_string}")
assert [%{"id" => ^id}] = json_response_and_validate_schema(conn, 200)
end
describe "getting statuses by ids with restricted unauthenticated for local and remote" do
setup do: local_and_remote_activities()
@ -937,7 +947,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true)
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
res_conn = get(conn, "/api/v1/statuses?ids[]=#{local.id}&ids[]=#{remote.id}")
res_conn = get(conn, "/api/v1/statuses?id[]=#{local.id}&id[]=#{remote.id}")
assert json_response_and_validate_schema(res_conn, 200) == []
end
@ -945,7 +955,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
test "if user is authenticated", %{local: local, remote: remote} do
%{conn: conn} = oauth_access(["read"])
res_conn = get(conn, "/api/v1/statuses?ids[]=#{local.id}&ids[]=#{remote.id}")
res_conn = get(conn, "/api/v1/statuses?id[]=#{local.id}&id[]=#{remote.id}")
assert length(json_response_and_validate_schema(res_conn, 200)) == 2
end
@ -957,7 +967,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
setup do: clear_config([:restrict_unauthenticated, :activities, :local], true)
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
res_conn = get(conn, "/api/v1/statuses?ids[]=#{local.id}&ids[]=#{remote.id}")
res_conn = get(conn, "/api/v1/statuses?id[]=#{local.id}&id[]=#{remote.id}")
remote_id = remote.id
assert [%{"id" => ^remote_id}] = json_response_and_validate_schema(res_conn, 200)
@ -966,7 +976,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
test "if user is authenticated", %{local: local, remote: remote} do
%{conn: conn} = oauth_access(["read"])
res_conn = get(conn, "/api/v1/statuses?ids[]=#{local.id}&ids[]=#{remote.id}")
res_conn = get(conn, "/api/v1/statuses?id[]=#{local.id}&id[]=#{remote.id}")
assert length(json_response_and_validate_schema(res_conn, 200)) == 2
end
@ -978,7 +988,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true)
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
res_conn = get(conn, "/api/v1/statuses?ids[]=#{local.id}&ids[]=#{remote.id}")
res_conn = get(conn, "/api/v1/statuses?id[]=#{local.id}&id[]=#{remote.id}")
local_id = local.id
assert [%{"id" => ^local_id}] = json_response_and_validate_schema(res_conn, 200)
@ -987,7 +997,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
test "if user is authenticated", %{local: local, remote: remote} do
%{conn: conn} = oauth_access(["read"])
res_conn = get(conn, "/api/v1/statuses?ids[]=#{local.id}&ids[]=#{remote.id}")
res_conn = get(conn, "/api/v1/statuses?id[]=#{local.id}&id[]=#{remote.id}")
assert length(json_response_and_validate_schema(res_conn, 200)) == 2
end
@ -2241,7 +2251,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
result =
conn
|> get("/api/v1/statuses/?ids[]=#{activity.id}")
|> get("/api/v1/statuses/?id[]=#{activity.id}")
|> json_response_and_validate_schema(200)
assert [
@ -2254,7 +2264,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
result =
conn
|> get("/api/v1/statuses/?ids[]=#{activity.id}&with_muted=true")
|> get("/api/v1/statuses/?id[]=#{activity.id}&with_muted=true")
|> json_response_and_validate_schema(200)
assert [

View file

@ -6,15 +6,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
use Pleroma.Web.ConnCase, async: true
describe "empty_array/2 (stubs)" do
test "GET /api/v1/accounts/:id/identity_proofs" do
%{user: user, conn: conn} = oauth_access(["read:accounts"])
assert [] ==
conn
|> get("/api/v1/accounts/#{user.id}/identity_proofs")
|> json_response(200)
end
test "GET /api/v1/endorsements" do
%{conn: conn} = oauth_access(["read:accounts"])

View file

@ -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(other_user, user)
{:ok, other_user, user, _} = CommonAPI.follow(other_user, user)
user = User.get_cached_by_id(user.id)
other_user = User.get_cached_by_id(other_user.id)
@ -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(other_user, user)
{:ok, _other_user, user, _activity} = CommonAPI.follow(user, other_user)
{:ok, other_user, user, _activity} = CommonAPI.follow(other_user, user)
{:ok, user, _other_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(other_user, user)
{:ok, other_user, 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(user, other_user)
{:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)
assert %{
followers_count: 1,
@ -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(user, other_user)
{:ok, user, _other_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(user, other_user)
{:ok, user, other_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(user, other_user)
{:ok, user, other_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(user, other_user)
{:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)
{:ok, user} = User.update_and_set_cache(user, %{is_locked: false})

View file

@ -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(followed, follower)
{:ok, followed, follower, _activity} = CommonAPI.follow(followed, follower)
notification = Notification |> Repo.one() |> Repo.preload(:activity)
expected = %{

View file

@ -20,9 +20,7 @@ defmodule Pleroma.Web.PleromaAPI.BackupControllerTest do
end
test "GET /api/v1/pleroma/backups", %{user: user, conn: conn} do
assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id}}} = Backup.create(user)
backup = Backup.get(backup_id)
assert {:ok, %Backup{} = backup} = Backup.user(user)
response =
conn

View file

@ -27,42 +27,11 @@ defmodule Pleroma.Web.PleromaAPI.BackupViewTest do
assert result.id == backup.id
end
test "it renders the state and processed_number" do
test "it renders the processed state" do
user = insert(:user)
backup = Backup.new(user)
result = BackupView.render("show.json", backup: backup)
assert result.state == to_string(backup.state)
assert result.processed_number == backup.processed_number
end
test "it renders failed state with legacy records" do
backup = %Backup{
id: 0,
content_type: "application/zip",
file_name: "dummy",
file_size: 1,
state: :invalid,
processed: true,
processed_number: 1,
inserted_at: NaiveDateTime.utc_now()
}
result = BackupView.render("show.json", backup: backup)
assert result.state == "complete"
backup = %Backup{
id: 0,
content_type: "application/zip",
file_name: "dummy",
file_size: 1,
state: :invalid,
processed: false,
processed_number: 1,
inserted_at: NaiveDateTime.utc_now()
}
result = BackupView.render("show.json", backup: backup)
assert result.state == "failed"
refute result.processed
end
end

View file

@ -0,0 +1,100 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.StreamerViewTest do
use Pleroma.Web.ConnCase, async: true
# import ExUnit.CaptureLog
import Pleroma.Factory
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.StreamerView
describe "follow_relationships_update.json" do
test "shows follower/following count normally" do
other_user = insert(:user)
%{id: following_id} = following = insert(:user)
follower = insert(:user)
{:ok, _, _, _} = CommonAPI.follow(other_user, following)
{:ok, following, follower, _activity} = CommonAPI.follow(following, follower)
result =
StreamerView.render(
"follow_relationships_update.json",
%{follower: follower, following: following, state: :test},
"user:test"
)
{:ok, %{"payload" => payload}} = Jason.decode(result)
{:ok, decoded_payload} = Jason.decode(payload)
# check the payload updating the user that was followed
assert match?(
%{"follower_count" => 1, "following_count" => 1, "id" => ^following_id},
decoded_payload["following"]
)
end
test "hides follower count for :hide_followers and :hide_followers_count" do
user_attrs = [%{hide_followers: true}, %{hide_followers_count: true}]
Enum.each(user_attrs, fn attrs ->
other_user = insert(:user)
%{id: following_id} = following = insert(:user, attrs)
follower = insert(:user)
{:ok, _, _, _} = CommonAPI.follow(other_user, following)
{:ok, following, follower, _activity} = CommonAPI.follow(following, follower)
result =
StreamerView.render(
"follow_relationships_update.json",
%{follower: follower, following: following, state: :test},
"user:test"
)
{:ok, %{"payload" => payload}} = Jason.decode(result)
{:ok, decoded_payload} = Jason.decode(payload)
# check the payload updating the user that was followed
assert match?(
%{"follower_count" => 0, "following_count" => 1, "id" => ^following_id},
decoded_payload["following"]
)
end)
end
test "hides follows count for :hide_follows and :hide_follows_count" do
user_attrs = [%{hide_follows: true}, %{hide_follows_count: true}]
Enum.each(user_attrs, fn attrs ->
other_user = insert(:user)
%{id: following_id} = following = insert(:user, attrs)
follower = insert(:user)
{:ok, _, _, _} = CommonAPI.follow(other_user, following)
{:ok, following, follower, _activity} = CommonAPI.follow(following, follower)
result =
StreamerView.render(
"follow_relationships_update.json",
%{follower: follower, following: following, state: :test},
"user:test"
)
{:ok, %{"payload" => payload}} = Jason.decode(result)
{:ok, decoded_payload} = Jason.decode(payload)
# check the payload updating the user that was followed
assert match?(
%{"follower_count" => 1, "following_count" => 0, "id" => ^following_id},
decoded_payload["following"]
)
end)
end
end
end

View file

@ -14,10 +14,12 @@ defmodule Pleroma.Workers.PurgeExpiredActivityTest do
activity = insert(:note_activity)
assert {:ok, _} =
PurgeExpiredActivity.enqueue(%{
activity_id: activity.id,
expires_at: DateTime.add(DateTime.utc_now(), 3601)
})
PurgeExpiredActivity.enqueue(
%{
activity_id: activity.id
},
scheduled_at: DateTime.add(DateTime.utc_now(), 3601)
)
assert_enqueued(
worker: Pleroma.Workers.PurgeExpiredActivity,
@ -34,10 +36,12 @@ defmodule Pleroma.Workers.PurgeExpiredActivityTest do
activity = insert(:note_activity)
assert {:ok, _} =
PurgeExpiredActivity.enqueue(%{
activity_id: activity.id,
expires_at: DateTime.add(DateTime.utc_now(), 3601)
})
PurgeExpiredActivity.enqueue(
%{
activity_id: activity.id
},
scheduled_at: DateTime.add(DateTime.utc_now(), 3601)
)
user = Pleroma.User.get_by_ap_id(activity.actor)
Pleroma.Repo.delete(user)
@ -48,10 +52,12 @@ defmodule Pleroma.Workers.PurgeExpiredActivityTest do
test "error if actiivity was not found" do
assert {:ok, _} =
PurgeExpiredActivity.enqueue(%{
activity_id: "some_id",
expires_at: DateTime.add(DateTime.utc_now(), 3601)
})
PurgeExpiredActivity.enqueue(
%{
activity_id: "some_id"
},
scheduled_at: DateTime.add(DateTime.utc_now(), 3601)
)
assert {:cancel, :activity_not_found} =
perform_job(Pleroma.Workers.PurgeExpiredActivity, %{activity_id: "some_if"})

View file

@ -12,6 +12,7 @@ defmodule Pleroma.Workers.RemoteFetcherWorkerTest do
@deleted_object_two "https://deleted-410.example.com/"
@unauthorized_object "https://unauthorized.example.com/"
@depth_object "https://depth.example.com/"
@content_type_object "https://bad_content_type.example.com/"
describe "RemoteFetcherWorker" do
setup do
@ -35,34 +36,48 @@ defmodule Pleroma.Workers.RemoteFetcherWorkerTest do
%Tesla.Env{
status: 200
}
%{method: :get, url: @content_type_object} ->
%Tesla.Env{
status: 200,
headers: [{"content-type", "application/json"}],
body: File.read!("test/fixtures/spoofed-object.json")
}
end)
end
test "does not requeue a deleted object" do
assert {:cancel, _} =
RemoteFetcherWorker.perform(%Oban.Job{
args: %{"op" => "fetch_remote", "id" => @deleted_object_one}
})
test "does not retry jobs for a deleted object" do
[
%{"op" => "fetch_remote", "id" => @deleted_object_one},
%{"op" => "fetch_remote", "id" => @deleted_object_two}
]
|> Enum.each(fn job -> assert {:cancel, _} = perform_job(RemoteFetcherWorker, job) end)
end
test "does not retry jobs for an unauthorized object" do
assert {:cancel, _} =
RemoteFetcherWorker.perform(%Oban.Job{
args: %{"op" => "fetch_remote", "id" => @deleted_object_two}
perform_job(RemoteFetcherWorker, %{
"op" => "fetch_remote",
"id" => @unauthorized_object
})
end
test "does not requeue an unauthorized object" do
assert {:cancel, _} =
RemoteFetcherWorker.perform(%Oban.Job{
args: %{"op" => "fetch_remote", "id" => @unauthorized_object}
})
end
test "does not requeue an object that exceeded depth" do
test "does not retry jobs for an an object that exceeded depth" do
clear_config([:instance, :federation_incoming_replies_max_depth], 0)
assert {:cancel, _} =
RemoteFetcherWorker.perform(%Oban.Job{
args: %{"op" => "fetch_remote", "id" => @depth_object, "depth" => 1}
perform_job(RemoteFetcherWorker, %{
"op" => "fetch_remote",
"id" => @depth_object,
"depth" => 1
})
end
test "does not retry jobs for when object returns wrong content type" do
assert {:cancel, _} =
perform_job(RemoteFetcherWorker, %{
"op" => "fetch_remote",
"id" => @content_type_object
})
end
end

View file

@ -53,6 +53,13 @@ defmodule Pleroma.Factory do
keys: pem
}
user
|> Map.put(:raw_bio, user.bio)
|> merge_attributes(Map.delete(attrs, :domain))
|> make_user_urls(attrs)
end
defp make_user_urls(user, attrs) do
urls =
if attrs[:local] == false do
base_domain = attrs[:domain] || Enum.random(["domain1.com", "domain2.com", "domain3.com"])
@ -60,26 +67,22 @@ defmodule Pleroma.Factory do
ap_id = "https://#{base_domain}/users/#{user.nickname}"
%{
ap_id: ap_id,
follower_address: ap_id <> "/followers",
following_address: ap_id <> "/following",
featured_address: ap_id <> "/collections/featured"
ap_id: attrs[:ap_id] || ap_id,
follower_address: attrs[:follower_address] || ap_id <> "/followers",
following_address: attrs[:following_address] || ap_id <> "/following",
featured_address: attrs[:featured_address] || ap_id <> "/collections/featured",
inbox: attrs[:inbox] || "https://#{base_domain}/inbox"
}
else
%{
ap_id: User.ap_id(user),
follower_address: User.ap_followers(user),
following_address: User.ap_following(user),
featured_address: User.ap_featured_collection(user)
ap_id: attrs[:ap_id] || User.ap_id(user),
follower_address: attrs[:follower_address] || User.ap_followers(user),
following_address: attrs[:following_address] || User.ap_following(user),
featured_address: attrs[:featured_address] || User.ap_featured_collection(user)
}
end
attrs = Map.delete(attrs, :domain)
user
|> Map.put(:raw_bio, user.bio)
|> Map.merge(urls)
|> merge_attributes(attrs)
Map.merge(user, urls)
end
def user_relationship_factory(attrs \\ %{}) do

View file

@ -32,6 +32,4 @@ Mox.defmock(Pleroma.StubbedHTTPSignaturesMock, for: Pleroma.HTTPSignaturesAPI)
Mox.defmock(Pleroma.LoggerMock, for: Pleroma.Logging)
Mox.defmock(Pleroma.User.Backup.ProcessorMock, for: Pleroma.User.Backup.ProcessorAPI)
Mox.defmock(Pleroma.Uploaders.S3.ExAwsMock, for: Pleroma.Uploaders.S3.ExAwsAPI)