From 0070b131304f12a4795095b59a33a31ae8b4fb32 Mon Sep 17 00:00:00 2001 From: Lain Soykaf Date: Fri, 24 Jul 2026 17:43:02 +0400 Subject: [PATCH] test(workers): replace publisher mocks with Mox --- lib/pleroma/web/federator.ex | 3 +- lib/pleroma/web/federator/publishing.ex | 1 + lib/pleroma/workers/publisher_worker.ex | 7 +- .../pleroma/workers/publisher_worker_test.exs | 117 ++++++++++-------- 4 files changed, 70 insertions(+), 58 deletions(-) diff --git a/lib/pleroma/web/federator.ex b/lib/pleroma/web/federator.ex index 90cd2e54a..88b267331 100644 --- a/lib/pleroma/web/federator.ex +++ b/lib/pleroma/web/federator.ex @@ -89,7 +89,8 @@ defmodule Pleroma.Web.Federator do # Job Worker Callbacks - @spec perform(atom(), any()) :: {:ok, any()} | {:error, any()} + @impl true + @spec perform(atom(), any()) :: :ok | {:ok, any()} | {:error, any()} def perform(:publish_one, params) do Publisher.prepare_one(params) |> Publisher.publish_one() diff --git a/lib/pleroma/web/federator/publishing.ex b/lib/pleroma/web/federator/publishing.ex index 3a242b8dc..889b6b83e 100644 --- a/lib/pleroma/web/federator/publishing.ex +++ b/lib/pleroma/web/federator/publishing.ex @@ -3,5 +3,6 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.Federator.Publishing do + @callback perform(atom(), any()) :: :ok | {:ok, any()} | {:error, any()} @callback publish(map()) :: any() end diff --git a/lib/pleroma/workers/publisher_worker.ex b/lib/pleroma/workers/publisher_worker.ex index 4ac0e218e..186f6f4ef 100644 --- a/lib/pleroma/workers/publisher_worker.ex +++ b/lib/pleroma/workers/publisher_worker.ex @@ -4,6 +4,7 @@ defmodule Pleroma.Workers.PublisherWorker do alias Pleroma.Activity + alias Pleroma.Config alias Pleroma.Instances alias Pleroma.Web.Federator @@ -19,7 +20,7 @@ defmodule Pleroma.Workers.PublisherWorker do @impl true def perform(%Job{args: %{"op" => "publish", "activity_id" => activity_id}}) do activity = Activity.get_by_id(activity_id) - Federator.perform(:publish, activity) + federator().perform(:publish, activity) end def perform(%Job{args: %{"op" => "publish_one", "params" => params}} = job) do @@ -35,7 +36,7 @@ defmodule Pleroma.Workers.PublisherWorker do if not Instances.reachable?(params.inbox) do {:cancel, :unreachable} else - case Federator.perform(:publish_one, params) do + case federator().perform(:publish_one, params) do {:ok, _} -> :ok @@ -57,6 +58,8 @@ defmodule Pleroma.Workers.PublisherWorker do @impl true def timeout(_job), do: :timer.seconds(10) + defp federator, do: Config.get([:pipeline, :federator], Federator) + @base_backoff 15 @pow 5 @impl true diff --git a/test/pleroma/workers/publisher_worker_test.exs b/test/pleroma/workers/publisher_worker_test.exs index 0e1b9d698..ddbbba910 100644 --- a/test/pleroma/workers/publisher_worker_test.exs +++ b/test/pleroma/workers/publisher_worker_test.exs @@ -6,8 +6,8 @@ defmodule Pleroma.Workers.PublisherWorkerTest do use Pleroma.DataCase, async: false use Oban.Testing, repo: Pleroma.Repo + import Mox import Pleroma.Factory - import Mock alias Pleroma.Instances alias Pleroma.Object @@ -15,6 +15,7 @@ defmodule Pleroma.Workers.PublisherWorkerTest do alias Pleroma.Web.ActivityPub.Builder alias Pleroma.Web.CommonAPI alias Pleroma.Web.Federator + alias Pleroma.Web.FederatorMock alias Pleroma.Workers.PublisherWorker describe "Oban job priority:" do @@ -56,49 +57,49 @@ defmodule Pleroma.Workers.PublisherWorkerTest do end test "marks server as unreachable only on final failure", %{activity: activity} do - with_mock Pleroma.Web.Federator, - perform: fn :publish_one, _params -> {:error, :connection_error} end do - # First attempt - job = %Oban.Job{ - args: %{ - "op" => "publish_one", - "params" => %{ - "inbox" => "https://example.com/inbox", - "activity_id" => activity.id - } - }, - attempt: 1, - max_attempts: 5 - } + expect(FederatorMock, :perform, 2, fn :publish_one, _params -> + {:error, :connection_error} + end) - assert {:error, :connection_error} = PublisherWorker.perform(job) - assert Instances.reachable?("https://example.com/inbox") + # First attempt + job = %Oban.Job{ + args: %{ + "op" => "publish_one", + "params" => %{ + "inbox" => "https://example.com/inbox", + "activity_id" => activity.id + } + }, + attempt: 1, + max_attempts: 5 + } - # Final attempt - job = %{job | attempt: 5} - assert {:error, :connection_error} = PublisherWorker.perform(job) - refute Instances.reachable?("https://example.com/inbox") - end + assert {:error, :connection_error} = PublisherWorker.perform(job) + assert Instances.reachable?("https://example.com/inbox") + + # Final attempt + job = %{job | attempt: 5} + assert {:error, :connection_error} = PublisherWorker.perform(job) + refute Instances.reachable?("https://example.com/inbox") end test "does not mark server as unreachable on successful publish", %{activity: activity} do - with_mock Pleroma.Web.Federator, - perform: fn :publish_one, _params -> {:ok, %{status: 200}} end do - job = %Oban.Job{ - args: %{ - "op" => "publish_one", - "params" => %{ - "inbox" => "https://example.com/inbox", - "activity_id" => activity.id - } - }, - attempt: 1, - max_attempts: 5 - } + expect(FederatorMock, :perform, fn :publish_one, _params -> {:ok, %{status: 200}} end) - assert :ok = PublisherWorker.perform(job) - assert Instances.reachable?("https://example.com/inbox") - end + job = %Oban.Job{ + args: %{ + "op" => "publish_one", + "params" => %{ + "inbox" => "https://example.com/inbox", + "activity_id" => activity.id + } + }, + attempt: 1, + max_attempts: 5 + } + + assert :ok = PublisherWorker.perform(job) + assert Instances.reachable?("https://example.com/inbox") end test "does not create atoms from unexpected job params", %{activity: activity} do @@ -106,24 +107,30 @@ defmodule Pleroma.Workers.PublisherWorkerTest do assert_raise ArgumentError, fn -> String.to_existing_atom(unknown_key) end - with_mock Pleroma.Web.Federator, - perform: fn :publish_one, _params -> {:ok, %{status: 200}} end do - job = %Oban.Job{ - args: %{ - "op" => "publish_one", - "params" => %{ - "inbox" => "https://example.com/inbox", - "activity_id" => activity.id, - unknown_key => "ignored" - } - }, - attempt: 1, - max_attempts: 5 - } + expect(FederatorMock, :perform, fn :publish_one, params -> + assert params == %{ + inbox: "https://example.com/inbox", + activity_id: activity.id + } - assert :ok = PublisherWorker.perform(job) - assert_raise ArgumentError, fn -> String.to_existing_atom(unknown_key) end - end + {:ok, %{status: 200}} + end) + + job = %Oban.Job{ + args: %{ + "op" => "publish_one", + "params" => %{ + "inbox" => "https://example.com/inbox", + "activity_id" => activity.id, + unknown_key => "ignored" + } + }, + attempt: 1, + max_attempts: 5 + } + + assert :ok = PublisherWorker.perform(job) + assert_raise ArgumentError, fn -> String.to_existing_atom(unknown_key) end end test "cancels job if server is unreachable", %{activity: activity} do