Merge pull request 'docs: Remove quarantine section' (#324) from norm/akkoma:remove...
authorfloatingghost <hannah@coffee-and-dreams.uk>
Thu, 1 Dec 2022 12:59:50 +0000 (12:59 +0000)
committerfloatingghost <hannah@coffee-and-dreams.uk>
Thu, 1 Dec 2022 12:59:50 +0000 (12:59 +0000)
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/324

19 files changed:
CHANGELOG.md
installation/download-mastofe-build.sh [deleted file]
lib/pleroma/user.ex
lib/pleroma/user/import.ex
lib/pleroma/web/api_spec/operations/account_operation.ex
lib/pleroma/web/api_spec/schemas/account.ex
lib/pleroma/web/mastodon_api/controllers/account_controller.ex
lib/pleroma/web/mastodon_api/controllers/status_controller.ex
lib/pleroma/web/mastodon_api/views/account_view.ex
lib/pleroma/web/mastodon_api/views/status_view.ex
lib/pleroma/workers/background_worker.ex
priv/repo/migrations/20220905011454_generate_unset_user_keys.exs
priv/repo/migrations/20221128103145_add_per_user_post_expiry.exs [new file with mode: 0644]
test/pleroma/emoji/formatter_test.exs
test/pleroma/user/import_test.exs
test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
test/pleroma/web/mastodon_api/update_credentials_test.exs
test/pleroma/web/mastodon_api/views/account_view_test.exs
test/pleroma/web/pleroma_api/controllers/user_import_controller_test.exs

index 4b7b7e836b579257ccc494cf49434e242b23f0df..b49f77428b514f96d613d7c42f92fec3f4255db6 100644 (file)
@@ -9,11 +9,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 ## Added
 - Config: HTTP timeout options, :pool\_timeout and :receive\_timeout
 - Added statistic gathering about instances which do/don't have signed fetches when they request from us
+- Ability to set a default post expiry time, after which the post will be deleted. If used in concert with ActivityExpiration MRF, the expiry which comes _sooner_ will be applied.
 
 ## Changed
 - MastoAPI: Accept BooleanLike input on `/api/v1/accounts/:id/follow` (fixes follows with mastodon.py)
 - Relays from akkoma are now off by default
 - NormalizeMarkup MRF is now on by default
+- Follow/Block/Mute imports now spin off into *n* tasks to avoid the oban timeout
 
 ## 2022.11
 
diff --git a/installation/download-mastofe-build.sh b/installation/download-mastofe-build.sh
deleted file mode 100755 (executable)
index ee353c4..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/bin/sh
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-project_id="74"
-project_branch="rebase/glitch-soc"
-static_dir="instance/static"
-# For bundling:
-# project_branch="pleroma"
-# static_dir="priv/static"
-
-if [ ! -d "${static_dir}" ]
-then
-       echo "Error: ${static_dir} directory is missing, are you sure you are running this script at the root of pleroma’s repository?"
-       exit 1
-fi
-
-last_modified="$(curl --fail -s -I 'https://git.pleroma.social/api/v4/projects/'${project_id}'/jobs/artifacts/'${project_branch}'/download?job=build' | grep '^Last-Modified:' | cut -d: -f2-)"
-
-echo "branch:${project_branch}"
-echo "Last-Modified:${last_modified}"
-
-artifact="mastofe.zip"
-
-if [ "${last_modified}x" = "x" ]
-then
-       echo "ERROR: Couldn't get the modification date of the latest build archive, maybe it expired, exiting..."
-       exit 1
-fi
-
-if [ -e mastofe.timestamp ] && [ "$(cat mastofe.timestamp)" = "${last_modified}" ]
-then
-       echo "MastoFE is up-to-date, exiting..."
-       exit 0
-fi
-
-curl --fail -c - "https://git.pleroma.social/api/v4/projects/${project_id}/jobs/artifacts/${project_branch}/download?job=build" -o "${artifact}" || exit
-
-# TODO: Update the emoji as well
-rm -fr "${static_dir}/sw.js" "${static_dir}/packs" || exit
-unzip -q "${artifact}" || exit
-
-cp public/assets/sw.js "${static_dir}/sw.js" || exit
-cp -r public/packs "${static_dir}/packs" || exit
-
-echo "${last_modified}" > mastofe.timestamp
-rm -fr public
-rm -i "${artifact}"
index eb907a2d86340d43caef83fa7a6e8a7f9182de6c..b0ab9d0cd6ada61835b7bad09019524b9edee2ef 100644 (file)
@@ -151,6 +151,7 @@ defmodule Pleroma.User do
     field(:is_suggested, :boolean, default: false)
     field(:last_status_at, :naive_datetime)
     field(:language, :string)
+    field(:status_ttl_days, :integer, default: nil)
 
     embeds_one(
       :notification_settings,
@@ -516,7 +517,8 @@ defmodule Pleroma.User do
         :pleroma_settings_store,
         :is_discoverable,
         :actor_type,
-        :disclose_client
+        :disclose_client,
+        :status_ttl_days
       ]
     )
     |> unique_constraint(:nickname)
@@ -524,6 +526,7 @@ defmodule Pleroma.User do
     |> validate_length(:bio, max: bio_limit)
     |> validate_length(:name, min: 1, max: name_limit)
     |> validate_inclusion(:actor_type, ["Person", "Service"])
+    |> validate_number(:status_ttl_days, greater_than: 0)
     |> put_fields()
     |> put_emoji()
     |> put_change_if_present(:bio, &{:ok, parse_bio(&1, struct)})
index 60cd18041dc7e927c4ec514163c2e4bbcb6f37a1..95c4ef34ea200a6966b0600cf0fa592925cff4be 100644 (file)
@@ -12,47 +12,32 @@ defmodule Pleroma.User.Import do
   require Logger
 
   @spec perform(atom(), User.t(), list()) :: :ok | list() | {:error, any()}
-  def perform(:mutes_import, %User{} = user, [_ | _] = identifiers) do
-    Enum.map(
-      identifiers,
-      fn identifier ->
-        with {:ok, %User{} = muted_user} <- User.get_or_fetch(identifier),
-             {:ok, _} <- User.mute(user, muted_user) do
-          muted_user
-        else
-          error -> handle_error(:mutes_import, identifier, error)
-        end
-      end
-    )
+  def perform(:mutes_import, %User{} = user, identifier) do
+    with {:ok, %User{} = muted_user} <- User.get_or_fetch(identifier),
+         {:ok, _} <- User.mute(user, muted_user) do
+      muted_user
+    else
+      error -> handle_error(:mutes_import, identifier, error)
+    end
   end
 
-  def perform(:blocks_import, %User{} = blocker, [_ | _] = identifiers) do
-    Enum.map(
-      identifiers,
-      fn identifier ->
-        with {:ok, %User{} = blocked} <- User.get_or_fetch(identifier),
-             {:ok, _block} <- CommonAPI.block(blocker, blocked) do
-          blocked
-        else
-          error -> handle_error(:blocks_import, identifier, error)
-        end
-      end
-    )
+  def perform(:blocks_import, %User{} = blocker, identifier) do
+    with {:ok, %User{} = blocked} <- User.get_or_fetch(identifier),
+         {:ok, _block} <- CommonAPI.block(blocker, blocked) do
+      blocked
+    else
+      error -> handle_error(:blocks_import, identifier, error)
+    end
   end
 
-  def perform(:follow_import, %User{} = follower, [_ | _] = identifiers) do
-    Enum.map(
-      identifiers,
-      fn identifier ->
-        with {:ok, %User{} = followed} <- User.get_or_fetch(identifier),
-             {:ok, follower, followed} <- User.maybe_direct_follow(follower, followed),
-             {:ok, _, _, _} <- CommonAPI.follow(follower, followed) do
-          followed
-        else
-          error -> handle_error(:follow_import, identifier, error)
-        end
-      end
-    )
+  def perform(:follow_import, %User{} = follower, identifier) do
+    with {:ok, %User{} = followed} <- User.get_or_fetch(identifier),
+         {:ok, follower, followed} <- User.maybe_direct_follow(follower, followed),
+         {:ok, _, _, _} <- CommonAPI.follow(follower, followed) do
+      followed
+    else
+      error -> handle_error(:follow_import, identifier, error)
+    end
   end
 
   def perform(_, _, _), do: :ok
@@ -62,24 +47,24 @@ defmodule Pleroma.User.Import do
     error
   end
 
-  def blocks_import(%User{} = blocker, [_ | _] = identifiers) do
-    BackgroundWorker.enqueue(
-      "blocks_import",
-      %{"user_id" => blocker.id, "identifiers" => identifiers}
+  defp enqueue_many(op, user, identifiers) do
+    Enum.map(
+      identifiers,
+      fn identifier ->
+        BackgroundWorker.enqueue(op, %{"user_id" => user.id, "identifier" => identifier})
+      end
     )
   end
 
+  def blocks_import(%User{} = blocker, [_ | _] = identifiers) do
+    enqueue_many("blocks_import", blocker, identifiers)
+  end
+
   def follow_import(%User{} = follower, [_ | _] = identifiers) do
-    BackgroundWorker.enqueue(
-      "follow_import",
-      %{"user_id" => follower.id, "identifiers" => identifiers}
-    )
+    enqueue_many("follow_import", follower, identifiers)
   end
 
   def mutes_import(%User{} = user, [_ | _] = identifiers) do
-    BackgroundWorker.enqueue(
-      "mutes_import",
-      %{"user_id" => user.id, "identifiers" => identifiers}
-    )
+    enqueue_many("mutes_import", user, identifiers)
   end
 end
index 359a73ac06e3ddcd45914d61f3835e902d67a077..e20f57fec3e7bed9adbb565587344144f572406c 100644 (file)
@@ -700,7 +700,13 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
           description:
             "Discovery (listing, indexing) of this account by external services (search bots etc.) is allowed."
         },
-        actor_type: ActorType
+        actor_type: ActorType,
+        status_ttl_days: %Schema{
+          type: :integer,
+          nullable: true,
+          description:
+            "Number of days after which statuses will be deleted. Set to -1 to disable."
+        }
       },
       example: %{
         bot: false,
@@ -720,7 +726,8 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
         allow_following_move: false,
         also_known_as: ["https://foo.bar/users/foo"],
         discoverable: false,
-        actor_type: "Person"
+        actor_type: "Person",
+        status_ttl_days: 30
       }
     }
   end
index 5d3ac9cd0dd3c82c75c9348b77d862e4a69c06dd..2693eaceb90cffb9dbd0b2ee7266cad70dae3abf 100644 (file)
@@ -109,6 +109,12 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Account do
           }
         }
       },
+      akkoma: %Schema{
+        type: :object,
+        properties: %{
+          note_ttl_days: %Schema{type: :integer}
+        }
+      },
       source: %Schema{
         type: :object,
         properties: %{
index 946c8544fe2fbd64a5c8e38598816cecf3fd5f27..80497a2527ea2eb2f8d7d2dc66cd231e3353f2a1 100644 (file)
@@ -175,6 +175,11 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
       value -> {:ok, value}
     end
 
+    status_ttl_days_value = fn
+      -1 -> {:ok, nil}
+      value -> {:ok, value}
+    end
+
     user_params =
       [
         :no_rich_text,
@@ -215,7 +220,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
       # Note: param name is indeed :discoverable (not an error)
       |> Maps.put_if_present(:is_discoverable, params[:discoverable])
       |> Maps.put_if_present(:language, Pleroma.Web.Gettext.normalize_locale(params[:language]))
+      |> Maps.put_if_present(:status_ttl_days, params[:status_ttl_days], status_ttl_days_value)
 
+    IO.inspect(user_params)
     # What happens here:
     #
     # We want to update the user through the pipeline, but the ActivityPub
index 31f3b3a8de095d7892cbc23505f3b960f2e9835e..338a35052ae9fb7331daea2a97d9d6326ff3d76f 100644 (file)
@@ -171,6 +171,16 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
       Map.put(params, :in_reply_to_status_id, params[:in_reply_to_id])
       |> put_application(conn)
 
+    expires_in_seconds =
+      if is_nil(user.status_ttl_days),
+        do: nil,
+        else: 60 * 60 * 24 * user.status_ttl_days
+
+    params =
+      if is_nil(expires_in_seconds),
+        do: params,
+        else: Map.put(params, :expires_in, expires_in_seconds)
+
     with {:ok, activity} <- CommonAPI.post(user, params) do
       try_render(conn, "show.json",
         activity: activity,
index a04ffaaf3a7d9d85a069f635ce16769f8efc0cf1..653a50e20aecc3a4b76eb70a16a56d8814399ccd 100644 (file)
@@ -287,7 +287,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
       },
       last_status_at: user.last_status_at,
       akkoma: %{
-        instance: render("instance.json", %{instance: instance})
+        instance: render("instance.json", %{instance: instance}),
+        status_ttl_days: user.status_ttl_days
       },
       # Pleroma extensions
       # Note: it's insecure to output :email but fully-qualified nickname may serve as safe stub
index 929641b8454f0d6fcafe0cf0dd336831a221eb78..cc58f803e6b2c7773c96f6b1ad21d7ce0f7830ee 100644 (file)
@@ -65,7 +65,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
   # This should be removed in a future version of Pleroma. Pleroma-FE currently
   # depends on this field, as well.
   defp get_context_id(%{data: %{"context" => context}}) when is_binary(context) do
-    use Bitwise
+    import Bitwise
 
     :erlang.crc32(context)
     |> band(bnot(0x8000_0000))
index 4db077232a850eac077dd98793496f217e2c8f36..9bd9899db59e4a741c1808c211fba5e06c370c7f 100644 (file)
@@ -25,10 +25,10 @@ defmodule Pleroma.Workers.BackgroundWorker do
     User.perform(:force_password_reset, user)
   end
 
-  def perform(%Job{args: %{"op" => op, "user_id" => user_id, "identifiers" => identifiers}})
+  def perform(%Job{args: %{"op" => op, "user_id" => user_id, "identifier" => identifier}})
       when op in ["blocks_import", "follow_import", "mutes_import"] do
     user = User.get_cached_by_id(user_id)
-    {:ok, User.Import.perform(String.to_atom(op), user, identifiers)}
+    {:ok, User.Import.perform(String.to_atom(op), user, identifier)}
   end
 
   def perform(%Job{
index 43bc7100bd639a3b61a79df549b70ff894dbc0f9..3b04bb4f3e88600f9aebdf091c0ef58ad8ba86c1 100644 (file)
@@ -14,14 +14,14 @@ defmodule Pleroma.Repo.Migrations.GenerateUnsetUserKeys do
       from(u in User,
         where: u.local == true,
         where: is_nil(u.keys),
-        select: u
+        select: u.id
       )
 
     Repo.stream(query)
     |> Enum.each(fn user ->
       with {:ok, pem} <- Keys.generate_rsa_pem() do
-        Ecto.Changeset.cast(user, %{keys: pem}, [:keys])
-        |> Repo.update()
+        Ecto.Changeset.cast(%User{id: user}, %{keys: pem}, [:keys])
+        |> Repo.update(returning: false)
       end
     end)
   end
diff --git a/priv/repo/migrations/20221128103145_add_per_user_post_expiry.exs b/priv/repo/migrations/20221128103145_add_per_user_post_expiry.exs
new file mode 100644 (file)
index 0000000..95c585c
--- /dev/null
@@ -0,0 +1,9 @@
+defmodule Pleroma.Repo.Migrations.AddPerUserPostExpiry do
+  use Ecto.Migration
+
+  def change do
+    alter table(:users) do
+      add(:status_ttl_days, :integer, null: true)
+    end
+  end
+end
index 3942f609fd0e85d65cc8d0fef1061aabeae82287..eafdd5a435eabdea744b5c4983dd0d552048043b 100644 (file)
@@ -11,7 +11,7 @@ defmodule Pleroma.Emoji.FormatterTest do
       text = "I love :firefox:"
 
       expected_result =
-        "I love <img class=\"emoji\" alt=\"firefox\" title=\"firefox\" src=\"/emoji/Firefox.gif\"/>"
+        "I love <img alt=\"firefox\" title=\"firefox\" src=\"/emoji/Firefox.gif\"/>"
 
       assert Formatter.emojify(text) == expected_result
     end
index 2be2ee75b1edf3ddc07a1f90ffc8619b71ca4a44..19d022529412525f2288771c07ffd22b91eedbfe 100644 (file)
@@ -25,11 +25,14 @@ defmodule Pleroma.User.ImportTest do
         user3.nickname
       ]
 
-      {:ok, job} = User.Import.follow_import(user1, identifiers)
+      [{:ok, job1}, {:ok, job2}] = User.Import.follow_import(user1, identifiers)
+
+      assert {:ok, result} = ObanHelpers.perform(job1)
+      assert result == refresh_record(user2)
+
+      assert {:ok, result} = ObanHelpers.perform(job2)
+      assert result == refresh_record(user3)
 
-      assert {:ok, result} = ObanHelpers.perform(job)
-      assert is_list(result)
-      assert result == [refresh_record(user2), refresh_record(user3)]
       assert User.following?(user1, user2)
       assert User.following?(user1, user3)
     end
@@ -44,11 +47,14 @@ defmodule Pleroma.User.ImportTest do
         user3.nickname
       ]
 
-      {:ok, job} = User.Import.blocks_import(user1, identifiers)
+      [{:ok, job1}, {:ok, job2}] = User.Import.blocks_import(user1, identifiers)
+
+      assert {:ok, result} = ObanHelpers.perform(job1)
+      assert result == user2
+
+      assert {:ok, result} = ObanHelpers.perform(job2)
+      assert result == user3
 
-      assert {:ok, result} = ObanHelpers.perform(job)
-      assert is_list(result)
-      assert result == [user2, user3]
       assert User.blocks?(user1, user2)
       assert User.blocks?(user1, user3)
     end
@@ -63,11 +69,14 @@ defmodule Pleroma.User.ImportTest do
         user3.nickname
       ]
 
-      {:ok, job} = User.Import.mutes_import(user1, identifiers)
+      [{:ok, job1}, {:ok, job2}] = User.Import.mutes_import(user1, identifiers)
+
+      assert {:ok, result} = ObanHelpers.perform(job1)
+      assert result == user2
+
+      assert {:ok, result} = ObanHelpers.perform(job2)
+      assert result == user3
 
-      assert {:ok, result} = ObanHelpers.perform(job)
-      assert is_list(result)
-      assert result == [user2, user3]
       assert User.mutes?(user1, user2)
       assert User.mutes?(user1, user3)
     end
index ea6ace69f5ac60529e6881b22651be1511d85725..cda4c9e03bedb093746870969c22a980b5acbdae 100644 (file)
@@ -126,6 +126,35 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
       )
     end
 
+    test "automatically setting a post expiry if status_ttl_days is set" do
+      user = insert(:user, status_ttl_days: 1)
+      %{user: _user, token: _token, conn: conn} = oauth_access(["write:statuses"], user: user)
+
+      conn =
+        conn
+        |> put_req_header("content-type", "application/json")
+        |> post("api/v1/statuses", %{
+          "status" => "aa chikichiki banban"
+        })
+
+      assert %{"id" => id} = json_response_and_validate_schema(conn, 200)
+
+      activity = Activity.get_by_id_with_object(id)
+      {:ok, expires_at, _} = DateTime.from_iso8601(activity.data["expires_at"])
+
+      assert Timex.diff(
+               expires_at,
+               DateTime.utc_now(),
+               :hours
+             ) == 23
+
+      assert_enqueued(
+        worker: Pleroma.Workers.PurgeExpiredActivity,
+        args: %{activity_id: id},
+        scheduled_at: DateTime.add(DateTime.utc_now(), 1 * 60 * 60 * 24)
+      )
+    end
+
     test "it fails to create a status if `expires_in` is less or equal than an hour", %{
       conn: conn
     } do
index 606467fa97a1436c3dfba47bf7d6e8eb18e362b0..435782d0ac58e592c3b1206fbba8685156621c67 100644 (file)
@@ -209,6 +209,26 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
       assert update_activity.data["object"]["name"] == "markorepairs"
     end
 
+    test "updates the user's default post expiry", %{conn: conn} do
+      conn = patch(conn, "/api/v1/accounts/update_credentials", %{"status_ttl_days" => "1"})
+
+      assert user_data = json_response_and_validate_schema(conn, 200)
+      assert user_data["akkoma"]["status_ttl_days"] == 1
+    end
+
+    test "resets the user's default post expiry", %{conn: conn} do
+      conn = patch(conn, "/api/v1/accounts/update_credentials", %{"status_ttl_days" => "-1"})
+
+      assert user_data = json_response_and_validate_schema(conn, 200)
+      assert is_nil(user_data["akkoma"]["status_ttl_days"])
+    end
+
+    test "does not allow negative integers other than -1 for TTL", %{conn: conn} do
+      conn = patch(conn, "/api/v1/accounts/update_credentials", %{"status_ttl_days" => "-2"})
+
+      assert user_data = json_response_and_validate_schema(conn, 403)
+    end
+
     test "updates the user's AKAs", %{conn: conn} do
       conn =
         patch(conn, "/api/v1/accounts/update_credentials", %{
index f4a5f4d50326673eec6e9549e5e0145aa85526a5..c9036d67d225165ddde7bc08572412c3be162b0d 100644 (file)
@@ -37,7 +37,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
         inserted_at: ~N[2017-08-15 15:47:06.597036],
         emoji: %{"karjalanpiirakka" => "/file.png"},
         raw_bio: "valid html. a\nb\nc\nd\nf '&<>\"",
-        also_known_as: ["https://shitposter.zone/users/shp"]
+        also_known_as: ["https://shitposter.zone/users/shp"],
+        status_ttl_days: 5
       })
 
     insert(:instance, %{host: "example.com", nodeinfo: %{version: "2.1"}})
@@ -61,7 +62,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
             "version" => "2.1"
           },
           favicon: nil
-        }
+        },
+        status_ttl_days: 5
       },
       avatar: "http://localhost:4001/images/avi.png",
       avatar_static: "http://localhost:4001/images/avi.png",
@@ -243,7 +245,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
           name: "localhost",
           favicon: "http://localhost:4001/favicon.png",
           nodeinfo: %{version: "2.0"}
-        }
+        },
+        status_ttl_days: nil
       },
       pleroma: %{
         ap_id: user.ap_id,
index d977bc3a22903a4104b75cb15a40770f6bed9bc6..f9175058d01c28f70add7b0bc688f18a45d8d1ec 100644 (file)
@@ -47,8 +47,8 @@ defmodule Pleroma.Web.PleromaAPI.UserImportControllerTest do
                  |> json_response_and_validate_schema(200)
 
         assert [{:ok, job_result}] = ObanHelpers.perform_all()
-        assert job_result == [refresh_record(user2)]
-        assert [%Pleroma.User{follower_count: 1}] = job_result
+        assert job_result == refresh_record(user2)
+        assert %Pleroma.User{follower_count: 1} = job_result
       end
     end
 
@@ -108,8 +108,8 @@ defmodule Pleroma.Web.PleromaAPI.UserImportControllerTest do
                |> post("/api/pleroma/follow_import", %{"list" => identifiers})
                |> json_response_and_validate_schema(200)
 
-      assert [{:ok, job_result}] = ObanHelpers.perform_all()
-      assert job_result == Enum.map(users, &refresh_record/1)
+      job_results = Enum.map(ObanHelpers.perform_all(), fn {:ok, result} -> result end)
+      assert job_results == Enum.map(users, &refresh_record/1)
     end
   end
 
@@ -141,8 +141,8 @@ defmodule Pleroma.Web.PleromaAPI.UserImportControllerTest do
                  })
                  |> json_response_and_validate_schema(200)
 
-        assert [{:ok, job_result}] = ObanHelpers.perform_all()
-        assert job_result == users
+        job_results = Enum.map(ObanHelpers.perform_all(), fn {:ok, result} -> result end)
+        assert job_results == users
       end
     end
 
@@ -165,8 +165,8 @@ defmodule Pleroma.Web.PleromaAPI.UserImportControllerTest do
                |> post("/api/pleroma/blocks_import", %{"list" => identifiers})
                |> json_response_and_validate_schema(200)
 
-      assert [{:ok, job_result}] = ObanHelpers.perform_all()
-      assert job_result == users
+      job_results = Enum.map(ObanHelpers.perform_all(), fn {:ok, result} -> result end)
+      assert job_results == users
     end
   end
 
@@ -183,12 +183,12 @@ defmodule Pleroma.Web.PleromaAPI.UserImportControllerTest do
                |> post("/api/pleroma/mutes_import", %{"list" => "#{user2.ap_id}"})
                |> json_response_and_validate_schema(200)
 
-      assert [{:ok, job_result}] = ObanHelpers.perform_all()
-      assert job_result == [user2]
+      job_results = Enum.map(ObanHelpers.perform_all(), fn {:ok, result} -> result end)
+      assert job_results == [user2]
       assert Pleroma.User.mutes?(user, user2)
     end
 
-    test "it imports mutes users from file", %{user: user, conn: conn} do
+    test "it imports muted users from file", %{user: user, conn: conn} do
       users = [user2, user3] = insert_list(2, :user)
 
       with_mocks([
@@ -202,8 +202,8 @@ defmodule Pleroma.Web.PleromaAPI.UserImportControllerTest do
                  })
                  |> json_response_and_validate_schema(200)
 
-        assert [{:ok, job_result}] = ObanHelpers.perform_all()
-        assert job_result == users
+        job_results = Enum.map(ObanHelpers.perform_all(), fn {:ok, result} -> result end)
+        assert job_results == users
         assert Enum.all?(users, &Pleroma.User.mutes?(user, &1))
       end
     end
@@ -227,8 +227,8 @@ defmodule Pleroma.Web.PleromaAPI.UserImportControllerTest do
                |> post("/api/pleroma/mutes_import", %{"list" => identifiers})
                |> json_response_and_validate_schema(200)
 
-      assert [{:ok, job_result}] = ObanHelpers.perform_all()
-      assert job_result == users
+      job_results = Enum.map(ObanHelpers.perform_all(), fn {:ok, result} -> result end)
+      assert job_results == users
       assert Enum.all?(users, &Pleroma.User.mutes?(user, &1))
     end
   end