summaryrefslogtreecommitdiff
path: root/test/support
diff options
context:
space:
mode:
Diffstat (limited to 'test/support')
-rw-r--r--test/support/builders/user_builder.ex4
-rw-r--r--test/support/captcha_mock.ex2
-rw-r--r--test/support/channel_case.ex1
-rw-r--r--test/support/cluster.ex218
-rw-r--r--test/support/conn_case.ex26
-rw-r--r--test/support/data_case.ex6
-rw-r--r--test/support/factory.ex196
-rw-r--r--test/support/helpers.ex73
-rw-r--r--test/support/http_request_mock.ex381
-rw-r--r--test/support/mrf_module_mock.ex13
-rw-r--r--test/support/oban_helpers.ex42
-rw-r--r--test/support/web_push_http_client_mock.ex2
12 files changed, 898 insertions, 66 deletions
diff --git a/test/support/builders/user_builder.ex b/test/support/builders/user_builder.ex
index f58e1b0ad..fcfea666f 100644
--- a/test/support/builders/user_builder.ex
+++ b/test/support/builders/user_builder.ex
@@ -9,7 +9,9 @@ defmodule Pleroma.Builders.UserBuilder do
nickname: "testname",
password_hash: Comeonin.Pbkdf2.hashpwsalt("test"),
bio: "A tester.",
- ap_id: "some id"
+ ap_id: "some id",
+ last_digest_emailed_at: NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second),
+ notification_settings: %Pleroma.User.NotificationSetting{}
}
Map.merge(user, data)
diff --git a/test/support/captcha_mock.ex b/test/support/captcha_mock.ex
index ef4e68bc5..65ca6b3bd 100644
--- a/test/support/captcha_mock.ex
+++ b/test/support/captcha_mock.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Captcha.Mock do
diff --git a/test/support/channel_case.ex b/test/support/channel_case.ex
index 466d8986f..4a4585844 100644
--- a/test/support/channel_case.ex
+++ b/test/support/channel_case.ex
@@ -23,6 +23,7 @@ defmodule Pleroma.Web.ChannelCase do
quote do
# Import conveniences for testing with channels
use Phoenix.ChannelTest
+ use Pleroma.Tests.Helpers
# The default endpoint for testing
@endpoint Pleroma.Web.Endpoint
diff --git a/test/support/cluster.ex b/test/support/cluster.ex
new file mode 100644
index 000000000..deb37f361
--- /dev/null
+++ b/test/support/cluster.ex
@@ -0,0 +1,218 @@
+defmodule Pleroma.Cluster do
+ @moduledoc """
+ Facilities for managing a cluster of slave VM's for federated testing.
+
+ ## Spawning the federated cluster
+
+ `spawn_cluster/1` spawns a map of slave nodes that are started
+ within the running VM. During startup, the slave node is sent all configuration
+ from the parent node, as well as all code. After receiving configuration and
+ code, the slave then starts all applications currently running on the parent.
+ The configuration passed to `spawn_cluster/1` overrides any parent application
+ configuration for the provided OTP app and key. This is useful for customizing
+ the Ecto database, Phoenix webserver ports, etc.
+
+ For example, to start a single federated VM named ":federated1", with the
+ Pleroma Endpoint running on port 4123, and with a database named
+ "pleroma_test1", you would run:
+
+ endpoint_conf = Application.fetch_env!(:pleroma, Pleroma.Web.Endpoint)
+ repo_conf = Application.fetch_env!(:pleroma, Pleroma.Repo)
+
+ Pleroma.Cluster.spawn_cluster(%{
+ :"federated1@127.0.0.1" => [
+ {:pleroma, Pleroma.Repo, Keyword.merge(repo_conf, database: "pleroma_test1")},
+ {:pleroma, Pleroma.Web.Endpoint,
+ Keyword.merge(endpoint_conf, http: [port: 4011], url: [port: 4011], server: true)}
+ ]
+ })
+
+ *Note*: application configuration for a given key is not merged,
+ so any customization requires first fetching the existing values
+ and merging yourself by providing the merged configuration,
+ such as above with the endpoint config and repo config.
+
+ ## Executing code within a remote node
+
+ Use the `within/2` macro to execute code within the context of a remote
+ federated node. The code block captures all local variable bindings from
+ the parent's context and returns the result of the expression after executing
+ it on the remote node. For example:
+
+ import Pleroma.Cluster
+
+ parent_value = 123
+
+ result =
+ within :"federated1@127.0.0.1" do
+ {node(), parent_value}
+ end
+
+ assert result == {:"federated1@127.0.0.1, 123}
+
+ *Note*: while local bindings are captured and available within the block,
+ other parent contexts like required, aliased, or imported modules are not
+ in scope. Those will need to be reimported/aliases/required within the block
+ as `within/2` is a remote procedure call.
+ """
+
+ @extra_apps Pleroma.Mixfile.application()[:extra_applications]
+
+ @doc """
+ Spawns the default Pleroma federated cluster.
+
+ Values before may be customized as needed for the test suite.
+ """
+ def spawn_default_cluster do
+ endpoint_conf = Application.fetch_env!(:pleroma, Pleroma.Web.Endpoint)
+ repo_conf = Application.fetch_env!(:pleroma, Pleroma.Repo)
+
+ spawn_cluster(%{
+ :"federated1@127.0.0.1" => [
+ {:pleroma, Pleroma.Repo, Keyword.merge(repo_conf, database: "pleroma_test_federated1")},
+ {:pleroma, Pleroma.Web.Endpoint,
+ Keyword.merge(endpoint_conf, http: [port: 4011], url: [port: 4011], server: true)}
+ ],
+ :"federated2@127.0.0.1" => [
+ {:pleroma, Pleroma.Repo, Keyword.merge(repo_conf, database: "pleroma_test_federated2")},
+ {:pleroma, Pleroma.Web.Endpoint,
+ Keyword.merge(endpoint_conf, http: [port: 4012], url: [port: 4012], server: true)}
+ ]
+ })
+ end
+
+ @doc """
+ Spawns a configured map of federated nodes.
+
+ See `Pleroma.Cluster` module documentation for details.
+ """
+ def spawn_cluster(node_configs) do
+ # Turn node into a distributed node with the given long name
+ :net_kernel.start([:"primary@127.0.0.1"])
+
+ # Allow spawned nodes to fetch all code from this node
+ {:ok, _} = :erl_boot_server.start([])
+ allow_boot("127.0.0.1")
+
+ silence_logger_warnings(fn ->
+ node_configs
+ |> Enum.map(&Task.async(fn -> start_slave(&1) end))
+ |> Enum.map(&Task.await(&1, 60_000))
+ end)
+ end
+
+ @doc """
+ Executes block of code again remote node.
+
+ See `Pleroma.Cluster` module documentation for details.
+ """
+ defmacro within(node, do: block) do
+ quote do
+ rpc(unquote(node), unquote(__MODULE__), :eval_quoted, [
+ unquote(Macro.escape(block)),
+ binding()
+ ])
+ end
+ end
+
+ @doc false
+ def eval_quoted(block, binding) do
+ {result, _binding} = Code.eval_quoted(block, binding, __ENV__)
+ result
+ end
+
+ defp start_slave({node_host, override_configs}) do
+ log(node_host, "booting federated VM")
+ {:ok, node} = :slave.start(~c"127.0.0.1", node_name(node_host), vm_args())
+ add_code_paths(node)
+ load_apps_and_transfer_configuration(node, override_configs)
+ ensure_apps_started(node)
+ {:ok, node}
+ end
+
+ def rpc(node, module, function, args) do
+ :rpc.block_call(node, module, function, args)
+ end
+
+ defp vm_args do
+ ~c"-loader inet -hosts 127.0.0.1 -setcookie #{:erlang.get_cookie()}"
+ end
+
+ defp allow_boot(host) do
+ {:ok, ipv4} = :inet.parse_ipv4_address(~c"#{host}")
+ :ok = :erl_boot_server.add_slave(ipv4)
+ end
+
+ defp add_code_paths(node) do
+ rpc(node, :code, :add_paths, [:code.get_path()])
+ end
+
+ defp load_apps_and_transfer_configuration(node, override_configs) do
+ Enum.each(Application.loaded_applications(), fn {app_name, _, _} ->
+ app_name
+ |> Application.get_all_env()
+ |> Enum.each(fn {key, primary_config} ->
+ rpc(node, Application, :put_env, [app_name, key, primary_config, [persistent: true]])
+ end)
+ end)
+
+ Enum.each(override_configs, fn {app_name, key, val} ->
+ rpc(node, Application, :put_env, [app_name, key, val, [persistent: true]])
+ end)
+ end
+
+ defp log(node, msg), do: IO.puts("[#{node}] #{msg}")
+
+ defp ensure_apps_started(node) do
+ loaded_names = Enum.map(Application.loaded_applications(), fn {name, _, _} -> name end)
+ app_names = @extra_apps ++ (loaded_names -- @extra_apps)
+
+ rpc(node, Application, :ensure_all_started, [:mix])
+ rpc(node, Mix, :env, [Mix.env()])
+ rpc(node, __MODULE__, :prepare_database, [])
+
+ log(node, "starting application")
+
+ Enum.reduce(app_names, MapSet.new(), fn app, loaded ->
+ if Enum.member?(loaded, app) do
+ loaded
+ else
+ {:ok, started} = rpc(node, Application, :ensure_all_started, [app])
+ MapSet.union(loaded, MapSet.new(started))
+ end
+ end)
+ end
+
+ @doc false
+ def prepare_database do
+ log(node(), "preparing database")
+ repo_config = Application.get_env(:pleroma, Pleroma.Repo)
+ repo_config[:adapter].storage_down(repo_config)
+ repo_config[:adapter].storage_up(repo_config)
+
+ {:ok, _, _} =
+ Ecto.Migrator.with_repo(Pleroma.Repo, fn repo ->
+ Ecto.Migrator.run(repo, :up, log: false, all: true)
+ end)
+
+ Ecto.Adapters.SQL.Sandbox.mode(Pleroma.Repo, :manual)
+ {:ok, _} = Application.ensure_all_started(:ex_machina)
+ end
+
+ defp silence_logger_warnings(func) do
+ prev_level = Logger.level()
+ Logger.configure(level: :error)
+ res = func.()
+ Logger.configure(level: prev_level)
+
+ res
+ end
+
+ defp node_name(node_host) do
+ node_host
+ |> to_string()
+ |> String.split("@")
+ |> Enum.at(0)
+ |> String.to_atom()
+ end
+end
diff --git a/test/support/conn_case.ex b/test/support/conn_case.ex
index ec5892ff5..22e72fc09 100644
--- a/test/support/conn_case.ex
+++ b/test/support/conn_case.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ConnCase do
@@ -28,6 +28,26 @@ defmodule Pleroma.Web.ConnCase do
# The default endpoint for testing
@endpoint Pleroma.Web.Endpoint
+
+ # Sets up OAuth access with specified scopes
+ defp oauth_access(scopes, opts \\ []) do
+ user =
+ Keyword.get_lazy(opts, :user, fn ->
+ Pleroma.Factory.insert(:user)
+ end)
+
+ token =
+ Keyword.get_lazy(opts, :oauth_token, fn ->
+ Pleroma.Factory.insert(:oauth_token, user: user, scopes: scopes)
+ end)
+
+ conn =
+ build_conn()
+ |> assign(:user, user)
+ |> assign(:token, token)
+
+ %{user: user, token: token, conn: conn}
+ end
end
end
@@ -40,6 +60,10 @@ defmodule Pleroma.Web.ConnCase do
Ecto.Adapters.SQL.Sandbox.mode(Pleroma.Repo, {:shared, self()})
end
+ if tags[:needs_streamer] do
+ start_supervised(Pleroma.Web.Streamer.supervisor())
+ end
+
{:ok, conn: Phoenix.ConnTest.build_conn()}
end
end
diff --git a/test/support/data_case.ex b/test/support/data_case.ex
index f3d98e7e3..4ffcbac9e 100644
--- a/test/support/data_case.ex
+++ b/test/support/data_case.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.DataCase do
@@ -39,6 +39,10 @@ defmodule Pleroma.DataCase do
Ecto.Adapters.SQL.Sandbox.mode(Pleroma.Repo, {:shared, self()})
end
+ if tags[:needs_streamer] do
+ start_supervised(Pleroma.Web.Streamer.supervisor())
+ end
+
:ok
end
diff --git a/test/support/factory.ex b/test/support/factory.ex
index 531eb81e4..780235cb9 100644
--- a/test/support/factory.ex
+++ b/test/support/factory.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Factory do
@@ -31,15 +31,27 @@ defmodule Pleroma.Factory do
nickname: sequence(:nickname, &"nick#{&1}"),
password_hash: Comeonin.Pbkdf2.hashpwsalt("test"),
bio: sequence(:bio, &"Tester Number #{&1}"),
- info: %{}
+ last_digest_emailed_at: NaiveDateTime.utc_now(),
+ notification_settings: %Pleroma.User.NotificationSetting{}
}
%{
user
| ap_id: User.ap_id(user),
follower_address: User.ap_followers(user),
- following_address: User.ap_following(user),
- following: [User.ap_id(user)]
+ following_address: User.ap_following(user)
+ }
+ end
+
+ def user_relationship_factory(attrs \\ %{}) do
+ source = attrs[:source] || insert(:user)
+ target = attrs[:target] || insert(:user)
+ relationship_type = attrs[:relationship_type] || :block
+
+ %Pleroma.UserRelationship{
+ source_id: source.id,
+ target_id: target.id,
+ relationship_type: relationship_type
}
end
@@ -70,6 +82,47 @@ defmodule Pleroma.Factory do
}
end
+ def audio_factory(attrs \\ %{}) do
+ text = sequence(:text, &"lain radio episode #{&1}")
+
+ user = attrs[:user] || insert(:user)
+
+ data = %{
+ "type" => "Audio",
+ "id" => Pleroma.Web.ActivityPub.Utils.generate_object_id(),
+ "artist" => "lain",
+ "title" => text,
+ "album" => "lain radio",
+ "to" => ["https://www.w3.org/ns/activitystreams#Public"],
+ "published" => DateTime.utc_now() |> DateTime.to_iso8601(),
+ "actor" => user.ap_id,
+ "length" => 180_000
+ }
+
+ %Pleroma.Object{
+ data: merge_attributes(data, Map.get(attrs, :data, %{}))
+ }
+ end
+
+ def listen_factory do
+ audio = insert(:audio)
+
+ data = %{
+ "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
+ "type" => "Listen",
+ "actor" => audio.data["actor"],
+ "to" => audio.data["to"],
+ "object" => audio.data,
+ "published" => audio.data["published"]
+ }
+
+ %Pleroma.Activity{
+ data: data,
+ actor: data["actor"],
+ recipients: data["to"]
+ }
+ end
+
def direct_note_factory do
user2 = insert(:user)
@@ -118,17 +171,21 @@ defmodule Pleroma.Factory do
def note_activity_factory(attrs \\ %{}) do
user = attrs[:user] || insert(:user)
note = attrs[:note] || insert(:note, user: user)
- attrs = Map.drop(attrs, [:user, :note])
- data = %{
- "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
- "type" => "Create",
- "actor" => note.data["actor"],
- "to" => note.data["to"],
- "object" => note.data["id"],
- "published" => DateTime.utc_now() |> DateTime.to_iso8601(),
- "context" => note.data["context"]
- }
+ data_attrs = attrs[:data_attrs] || %{}
+ attrs = Map.drop(attrs, [:user, :note, :data_attrs])
+
+ data =
+ %{
+ "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
+ "type" => "Create",
+ "actor" => note.data["actor"],
+ "to" => note.data["to"],
+ "object" => note.data["id"],
+ "published" => DateTime.utc_now() |> DateTime.to_iso8601(),
+ "context" => note.data["context"]
+ }
+ |> Map.merge(data_attrs)
%Pleroma.Activity{
data: data,
@@ -138,6 +195,25 @@ defmodule Pleroma.Factory do
|> Map.merge(attrs)
end
+ defp expiration_offset_by_minutes(attrs, minutes) do
+ scheduled_at =
+ NaiveDateTime.utc_now()
+ |> NaiveDateTime.add(:timer.minutes(minutes), :millisecond)
+ |> NaiveDateTime.truncate(:second)
+
+ %Pleroma.ActivityExpiration{}
+ |> Map.merge(attrs)
+ |> Map.put(:scheduled_at, scheduled_at)
+ end
+
+ def expiration_in_the_past_factory(attrs \\ %{}) do
+ expiration_offset_by_minutes(attrs, -60)
+ end
+
+ def expiration_in_the_future_factory(attrs \\ %{}) do
+ expiration_offset_by_minutes(attrs, 61)
+ end
+
def article_activity_factory do
article = insert(:article)
@@ -178,18 +254,20 @@ defmodule Pleroma.Factory do
}
end
- def like_activity_factory do
- note_activity = insert(:note_activity)
+ def like_activity_factory(attrs \\ %{}) do
+ note_activity = attrs[:note_activity] || insert(:note_activity)
object = Object.normalize(note_activity)
user = insert(:user)
- data = %{
- "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
- "actor" => user.ap_id,
- "type" => "Like",
- "object" => object.data["id"],
- "published_at" => DateTime.utc_now() |> DateTime.to_iso8601()
- }
+ data =
+ %{
+ "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
+ "actor" => user.ap_id,
+ "type" => "Like",
+ "object" => object.data["id"],
+ "published_at" => DateTime.utc_now() |> DateTime.to_iso8601()
+ }
+ |> Map.merge(attrs[:data_attrs] || %{})
%Pleroma.Activity{
data: data
@@ -214,31 +292,11 @@ defmodule Pleroma.Factory do
}
end
- def websub_subscription_factory do
- %Pleroma.Web.Websub.WebsubServerSubscription{
- topic: "http://example.org",
- callback: "http://example.org/callback",
- secret: "here's a secret",
- valid_until: NaiveDateTime.add(NaiveDateTime.utc_now(), 100),
- state: "requested"
- }
- end
-
- def websub_client_subscription_factory do
- %Pleroma.Web.Websub.WebsubClientSubscription{
- topic: "http://example.org",
- secret: "here's a secret",
- valid_until: nil,
- state: "requested",
- subscribers: []
- }
- end
-
def oauth_app_factory do
%Pleroma.Web.OAuth.App{
client_name: "Some client",
redirect_uris: "https://example.com/callback",
- scopes: ["read", "write", "follow", "push"],
+ scopes: ["read", "write", "follow", "push", "admin"],
website: "https://example.com",
client_id: Ecto.UUID.generate(),
client_secret: "aaa;/&bbb"
@@ -252,18 +310,37 @@ defmodule Pleroma.Factory do
}
end
- def oauth_token_factory do
- oauth_app = insert(:oauth_app)
+ def oauth_token_factory(attrs \\ %{}) do
+ scopes = Map.get(attrs, :scopes, ["read"])
+ oauth_app = Map.get_lazy(attrs, :app, fn -> insert(:oauth_app, scopes: scopes) end)
+ user = Map.get_lazy(attrs, :user, fn -> build(:user) end)
+
+ valid_until =
+ Map.get(attrs, :valid_until, NaiveDateTime.add(NaiveDateTime.utc_now(), 60 * 10))
%Pleroma.Web.OAuth.Token{
token: :crypto.strong_rand_bytes(32) |> Base.url_encode64(),
refresh_token: :crypto.strong_rand_bytes(32) |> Base.url_encode64(),
- user: build(:user),
- app_id: oauth_app.id,
- valid_until: NaiveDateTime.add(NaiveDateTime.utc_now(), 60 * 10)
+ scopes: scopes,
+ user: user,
+ app: oauth_app,
+ valid_until: valid_until
}
end
+ def oauth_admin_token_factory(attrs \\ %{}) do
+ user = Map.get_lazy(attrs, :user, fn -> build(:user, is_admin: true) end)
+
+ scopes =
+ attrs
+ |> Map.get(:scopes, ["admin"])
+ |> Kernel.++(["admin"])
+ |> Enum.uniq()
+
+ attrs = Map.merge(attrs, %{user: user, scopes: scopes})
+ oauth_token_factory(attrs)
+ end
+
def oauth_authorization_factory do
%Pleroma.Web.OAuth.Authorization{
token: :crypto.strong_rand_bytes(32) |> Base.url_encode64(padding: false),
@@ -317,9 +394,15 @@ defmodule Pleroma.Factory do
end
def config_factory do
- %Pleroma.Web.AdminAPI.Config{
- key: sequence(:key, &"some_key_#{&1}"),
- group: "pleroma",
+ %Pleroma.ConfigDB{
+ key:
+ sequence(:key, fn key ->
+ # Atom dynamic registration hack in tests
+ "some_key_#{key}"
+ |> String.to_atom()
+ |> inspect()
+ end),
+ group: ":pleroma",
value:
sequence(
:value,
@@ -329,4 +412,13 @@ defmodule Pleroma.Factory do
)
}
end
+
+ def marker_factory do
+ %Pleroma.Marker{
+ user: build(:user),
+ timeline: "notifications",
+ lock_version: 0,
+ last_read_id: "1"
+ }
+ end
end
diff --git a/test/support/helpers.ex b/test/support/helpers.ex
index 1a92be065..9f817622d 100644
--- a/test/support/helpers.ex
+++ b/test/support/helpers.ex
@@ -1,14 +1,59 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Tests.Helpers do
@moduledoc """
Helpers for use in tests.
"""
+ alias Pleroma.Config
+
+ defmacro clear_config(config_path) do
+ quote do
+ clear_config(unquote(config_path)) do
+ end
+ end
+ end
+
+ defmacro clear_config(config_path, do: yield) do
+ quote do
+ setup do
+ initial_setting = Config.get(unquote(config_path))
+ unquote(yield)
+ on_exit(fn -> Config.put(unquote(config_path), initial_setting) end)
+ :ok
+ end
+ end
+ end
+
+ defmacro clear_config_all(config_path) do
+ quote do
+ clear_config_all(unquote(config_path)) do
+ end
+ end
+ end
+
+ defmacro clear_config_all(config_path, do: yield) do
+ quote do
+ setup_all do
+ initial_setting = Config.get(unquote(config_path))
+ unquote(yield)
+ on_exit(fn -> Config.put(unquote(config_path), initial_setting) end)
+ :ok
+ end
+ end
+ end
defmacro __using__(_opts) do
quote do
+ import Pleroma.Tests.Helpers,
+ only: [
+ clear_config: 1,
+ clear_config: 2,
+ clear_config_all: 1,
+ clear_config_all: 2
+ ]
+
def collect_ids(collection) do
collection
|> Enum.map(& &1.id)
@@ -30,6 +75,32 @@ defmodule Pleroma.Tests.Helpers do
|> Poison.encode!()
|> Poison.decode!()
end
+
+ def stringify_keys(nil), do: nil
+
+ def stringify_keys(key) when key in [true, false], do: key
+ def stringify_keys(key) when is_atom(key), do: Atom.to_string(key)
+
+ def stringify_keys(map) when is_map(map) do
+ map
+ |> Enum.map(fn {k, v} -> {stringify_keys(k), stringify_keys(v)} end)
+ |> Enum.into(%{})
+ end
+
+ def stringify_keys([head | rest] = list) when is_list(list) do
+ [stringify_keys(head) | stringify_keys(rest)]
+ end
+
+ def stringify_keys(key), do: key
+
+ defmacro guards_config(config_path) do
+ quote do
+ initial_setting = Config.get(config_path)
+
+ Config.put(config_path, true)
+ on_exit(fn -> Config.put(config_path, initial_setting) end)
+ end
+ end
end
end
end
diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex
index 7811f7807..f43de700d 100644
--- a/test/support/http_request_mock.ex
+++ b/test/support/http_request_mock.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule HttpRequestMock do
@@ -17,9 +17,12 @@ defmodule HttpRequestMock do
with {:ok, res} <- apply(__MODULE__, method, [url, query, body, headers]) do
res
else
- {_, _r} = error ->
- # Logger.warn(r)
- error
+ error ->
+ with {:error, message} <- error do
+ Logger.warn(message)
+ end
+
+ {_, _r} = error
end
end
@@ -35,6 +38,14 @@ defmodule HttpRequestMock do
}}
end
+ def get("https://shitposter.club/users/moonman", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/moonman@shitposter.club.json")
+ }}
+ end
+
def get("https://mastodon.social/users/emelie/statuses/101849165031453009", _, _, _) do
{:ok,
%Tesla.Env{
@@ -43,6 +54,14 @@ defmodule HttpRequestMock do
}}
end
+ def get("https://mastodon.social/users/emelie/statuses/101849165031453404", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 404,
+ body: ""
+ }}
+ end
+
def get("https://mastodon.social/users/emelie", _, _, _) do
{:ok,
%Tesla.Env{
@@ -51,6 +70,10 @@ defmodule HttpRequestMock do
}}
end
+ def get("https://mastodon.social/users/not_found", _, _, _) do
+ {:ok, %Tesla.Env{status: 404}}
+ end
+
def get("https://mastodon.sdf.org/users/rinpatch", _, _, _) do
{:ok,
%Tesla.Env{
@@ -285,6 +308,24 @@ defmodule HttpRequestMock do
}}
end
+ def get("https://mobilizon.org/events/252d5816-00a3-4a89-a66f-15bf65c33e39", _, _,
+ Accept: "application/activity+json"
+ ) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/mobilizon.org-event.json")
+ }}
+ end
+
+ def get("https://mobilizon.org/@tcit", _, _, Accept: "application/activity+json") do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/mobilizon.org-user.json")
+ }}
+ end
+
def get("https://baptiste.gelez.xyz/@/BaptisteGelez", _, _, _) do
{:ok,
%Tesla.Env{
@@ -301,6 +342,22 @@ defmodule HttpRequestMock do
}}
end
+ def get("https://wedistribute.org/wp-json/pterotype/v1/object/85810", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/wedistribute-article.json")
+ }}
+ end
+
+ def get("https://wedistribute.org/wp-json/pterotype/v1/actor/-blog", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/wedistribute-user.json")
+ }}
+ end
+
def get("http://mastodon.example.org/users/admin", _, _, Accept: "application/activity+json") do
{:ok,
%Tesla.Env{
@@ -309,10 +366,193 @@ defmodule HttpRequestMock do
}}
end
+ def get("http://mastodon.example.org/users/relay", _, _, Accept: "application/activity+json") do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/relay@mastdon.example.org.json")
+ }}
+ end
+
def get("http://mastodon.example.org/users/gargron", _, _, Accept: "application/activity+json") do
{:error, :nxdomain}
end
+ def get("http://osada.macgirvin.com/.well-known/host-meta", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 404,
+ body: ""
+ }}
+ end
+
+ def get("https://osada.macgirvin.com/.well-known/host-meta", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 404,
+ body: ""
+ }}
+ end
+
+ def get("http://mastodon.sdf.org/.well-known/host-meta", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/sdf.org_host_meta")
+ }}
+ end
+
+ def get("https://mastodon.sdf.org/.well-known/host-meta", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/sdf.org_host_meta")
+ }}
+ end
+
+ def get(
+ "https://mastodon.sdf.org/.well-known/webfinger?resource=https://mastodon.sdf.org/users/snowdusk",
+ _,
+ _,
+ _
+ ) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/snowdusk@sdf.org_host_meta.json")
+ }}
+ end
+
+ def get("http://mstdn.jp/.well-known/host-meta", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/mstdn.jp_host_meta")
+ }}
+ end
+
+ def get("https://mstdn.jp/.well-known/host-meta", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/mstdn.jp_host_meta")
+ }}
+ end
+
+ def get("https://mstdn.jp/.well-known/webfinger?resource=kpherox@mstdn.jp", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/kpherox@mstdn.jp.xml")
+ }}
+ end
+
+ def get("http://mamot.fr/.well-known/host-meta", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/mamot.fr_host_meta")
+ }}
+ end
+
+ def get("https://mamot.fr/.well-known/host-meta", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/mamot.fr_host_meta")
+ }}
+ end
+
+ def get(
+ "https://mamot.fr/.well-known/webfinger?resource=https://mamot.fr/users/Skruyb",
+ _,
+ _,
+ _
+ ) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/skruyb@mamot.fr.atom")
+ }}
+ end
+
+ def get("http://pawoo.net/.well-known/host-meta", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/pawoo.net_host_meta")
+ }}
+ end
+
+ def get("https://pawoo.net/.well-known/host-meta", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/pawoo.net_host_meta")
+ }}
+ end
+
+ def get(
+ "https://pawoo.net/.well-known/webfinger?resource=https://pawoo.net/users/pekorino",
+ _,
+ _,
+ _
+ ) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/pekorino@pawoo.net_host_meta.json")
+ }}
+ end
+
+ def get("http://zetsubou.xn--q9jyb4c/.well-known/host-meta", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/xn--q9jyb4c_host_meta")
+ }}
+ end
+
+ def get("https://zetsubou.xn--q9jyb4c/.well-known/host-meta", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/xn--q9jyb4c_host_meta")
+ }}
+ end
+
+ def get("http://pleroma.soykaf.com/.well-known/host-meta", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/soykaf.com_host_meta")
+ }}
+ end
+
+ def get("https://pleroma.soykaf.com/.well-known/host-meta", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/soykaf.com_host_meta")
+ }}
+ end
+
+ def get("http://social.stopwatchingus-heidelberg.de/.well-known/host-meta", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/stopwatchingus-heidelberg.de_host_meta")
+ }}
+ end
+
+ def get("https://social.stopwatchingus-heidelberg.de/.well-known/host-meta", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/stopwatchingus-heidelberg.de_host_meta")
+ }}
+ end
+
def get(
"http://mastodon.example.org/@admin/99541947525187367",
_,
@@ -326,6 +566,14 @@ defmodule HttpRequestMock do
}}
end
+ def get("http://mastodon.example.org/@admin/99541947525187368", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 404,
+ body: ""
+ }}
+ end
+
def get("https://shitposter.club/notice/7369654", _, _, _) do
{:ok,
%Tesla.Env{
@@ -406,7 +654,7 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
- body: File.read!("test/fixtures/tesla_mock/https___shitposter.club_notice_2827873.html")
+ body: File.read!("test/fixtures/tesla_mock/https___shitposter.club_notice_2827873.json")
}}
end
@@ -614,6 +862,15 @@ defmodule HttpRequestMock do
}}
end
+ def get(
+ "https://social.heldscal.la/.well-known/webfinger?resource=invalid_content@social.heldscal.la",
+ _,
+ _,
+ Accept: "application/xrd+xml,application/jrd+json"
+ ) do
+ {:ok, %Tesla.Env{status: 200, body: ""}}
+ end
+
def get("http://framatube.org/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
@@ -743,6 +1000,11 @@ defmodule HttpRequestMock do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/lambadalambda.json")}}
end
+ def get("https://apfed.club/channel/indio", _, _, _) do
+ {:ok,
+ %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/osada-user-indio.json")}}
+ end
+
def get("https://social.heldscal.la/user/23211", _, _, Accept: "application/activity+json") do
{:ok, Tesla.Mock.json(%{"id" => "https://social.heldscal.la/user/23211"}, status: 200)}
end
@@ -767,6 +1029,14 @@ defmodule HttpRequestMock do
}}
end
+ def get("http://localhost:4001/users/masto_closed/followers?page=1", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/users_mock/masto_closed_followers_page.json")
+ }}
+ end
+
def get("http://localhost:4001/users/masto_closed/following", _, _, _) do
{:ok,
%Tesla.Env{
@@ -775,6 +1045,30 @@ defmodule HttpRequestMock do
}}
end
+ def get("http://localhost:4001/users/masto_closed/following?page=1", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/users_mock/masto_closed_following_page.json")
+ }}
+ end
+
+ def get("http://localhost:8080/followers/fuser3", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/users_mock/friendica_followers.json")
+ }}
+ end
+
+ def get("http://localhost:8080/following/fuser3", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/users_mock/friendica_following.json")
+ }}
+ end
+
def get("http://localhost:4001/users/fuser2/followers", _, _, _) do
{:ok,
%Tesla.Env{
@@ -915,9 +1209,77 @@ defmodule HttpRequestMock do
{:ok, %Tesla.Env{status: 404, body: ""}}
end
+ def get("https://mstdn.jp/.well-known/webfinger?resource=acct:kpherox@mstdn.jp", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/kpherox@mstdn.jp.xml")
+ }}
+ end
+
+ def get("https://10.111.10.1/notice/9kCP7V", _, _, _) do
+ {:ok, %Tesla.Env{status: 200, body: ""}}
+ end
+
+ def get("https://172.16.32.40/notice/9kCP7V", _, _, _) do
+ {:ok, %Tesla.Env{status: 200, body: ""}}
+ end
+
+ def get("https://192.168.10.40/notice/9kCP7V", _, _, _) do
+ {:ok, %Tesla.Env{status: 200, body: ""}}
+ end
+
+ def get("https://www.patreon.com/posts/mastodon-2-9-and-28121681", _, _, _) do
+ {:ok, %Tesla.Env{status: 200, body: ""}}
+ end
+
+ def get("http://mastodon.example.org/@admin/99541947525187367", _, _, _) do
+ {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/mastodon-post-activity.json")}}
+ end
+
+ def get("https://info.pleroma.site/activity4.json", _, _, _) do
+ {:ok, %Tesla.Env{status: 500, body: "Error occurred"}}
+ end
+
+ def get("http://example.com/rel_me/anchor", _, _, _) do
+ {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_anchor.html")}}
+ end
+
+ def get("http://example.com/rel_me/anchor_nofollow", _, _, _) do
+ {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_anchor_nofollow.html")}}
+ end
+
+ def get("http://example.com/rel_me/link", _, _, _) do
+ {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_link.html")}}
+ end
+
+ def get("http://example.com/rel_me/null", _, _, _) do
+ {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_null.html")}}
+ end
+
+ def get("https://skippers-bin.com/notes/7x9tmrp97i", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/misskey_poll_no_end_date.json")
+ }}
+ end
+
+ def get("https://skippers-bin.com/users/7v1w1r8ce6", _, _, _) do
+ {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/sjw.json")}}
+ end
+
+ def get("https://patch.cx/users/rin", _, _, _) do
+ {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/rin.json")}}
+ end
+
+ def get("http://example.com/rel_me/error", _, _, _) do
+ {:ok, %Tesla.Env{status: 404, body: ""}}
+ end
+
def get(url, query, body, headers) do
{:error,
- "Not implemented the mock response for get #{inspect(url)}, #{query}, #{inspect(body)}, #{
+ "Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{
inspect(headers)
}"}
end
@@ -979,7 +1341,10 @@ defmodule HttpRequestMock do
}}
end
- def post(url, _query, _body, _headers) do
- {:error, "Not implemented the mock response for post #{inspect(url)}"}
+ def post(url, query, body, headers) do
+ {:error,
+ "Mock response not implemented for POST #{inspect(url)}, #{query}, #{inspect(body)}, #{
+ inspect(headers)
+ }"}
end
end
diff --git a/test/support/mrf_module_mock.ex b/test/support/mrf_module_mock.ex
new file mode 100644
index 000000000..632c7ff1d
--- /dev/null
+++ b/test/support/mrf_module_mock.ex
@@ -0,0 +1,13 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule MRFModuleMock do
+ @behaviour Pleroma.Web.ActivityPub.MRF
+
+ @impl true
+ def filter(message), do: {:ok, message}
+
+ @impl true
+ def describe, do: {:ok, %{mrf_module_mock: "some config data"}}
+end
diff --git a/test/support/oban_helpers.ex b/test/support/oban_helpers.ex
new file mode 100644
index 000000000..72792c064
--- /dev/null
+++ b/test/support/oban_helpers.ex
@@ -0,0 +1,42 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Tests.ObanHelpers do
+ @moduledoc """
+ Oban test helpers.
+ """
+
+ alias Pleroma.Repo
+
+ def perform_all do
+ Oban.Job
+ |> Repo.all()
+ |> perform()
+ end
+
+ def perform(%Oban.Job{} = job) do
+ res = apply(String.to_existing_atom("Elixir." <> job.worker), :perform, [job.args, job])
+ Repo.delete(job)
+ res
+ end
+
+ def perform(jobs) when is_list(jobs) do
+ for job <- jobs, do: perform(job)
+ end
+
+ def member?(%{} = job_args, jobs) when is_list(jobs) do
+ Enum.any?(jobs, fn job ->
+ member?(job_args, job.args)
+ end)
+ end
+
+ def member?(%{} = test_attrs, %{} = attrs) do
+ Enum.all?(
+ test_attrs,
+ fn {k, _v} -> member?(test_attrs[k], attrs[k]) end
+ )
+ end
+
+ def member?(x, y), do: x == y
+end
diff --git a/test/support/web_push_http_client_mock.ex b/test/support/web_push_http_client_mock.ex
index d8accd21c..1d6ccff7e 100644
--- a/test/support/web_push_http_client_mock.ex
+++ b/test/support/web_push_http_client_mock.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.WebPushHttpClientMock do