Merge branch '2260-wrong-report-link' into 'develop'
authorlain <lain@soykaf.club>
Tue, 10 Nov 2020 11:04:19 +0000 (11:04 +0000)
committerlain <lain@soykaf.club>
Tue, 10 Nov 2020 11:04:19 +0000 (11:04 +0000)
Resolve "Wrong user link in Report email"

Closes #2260

See merge request pleroma/pleroma!3121

30 files changed:
CHANGELOG.md
config/config.exs
docs/API/differences_in_mastoapi_responses.md
docs/administration/CLI_tasks/release_environments.md [deleted file]
docs/installation/debian_based_en.md
docs/installation/otp_en.md
installation/init.d/pleroma
installation/pleroma.service
lib/mix/tasks/pleroma/instance.ex
lib/mix/tasks/pleroma/release_env.ex [deleted file]
lib/pleroma/stats.ex
lib/pleroma/user.ex
lib/pleroma/web/api_spec/operations/account_operation.ex
lib/pleroma/web/api_spec/operations/status_operation.ex
lib/pleroma/web/common_api.ex
lib/pleroma/web/fallback/redirect_controller.ex
lib/pleroma/web/feed/feed_view.ex
lib/pleroma/web/mastodon_api/controllers/account_controller.ex
lib/pleroma/web/mastodon_api/controllers/status_controller.ex
lib/pleroma/web/templates/feed/feed/_activity.atom.eex
lib/pleroma/web/templates/feed/feed/_activity.rss.eex
lib/pleroma/workers/mute_expire_worker.ex [new file with mode: 0644]
test/mix/tasks/pleroma/instance_test.exs
test/mix/tasks/pleroma/release_env_test.exs [deleted file]
test/pleroma/notification_test.exs
test/pleroma/user_test.exs
test/pleroma/web/common_api_test.exs
test/pleroma/web/feed/user_controller_test.exs
test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs
test/pleroma/web/mastodon_api/views/account_view_test.exs

index 756939ddebcc3366f79c2f9bbf50c6f7b199c892..b15ddb9433bb8cc91f5bda67c26008d55565b6a2 100644 (file)
@@ -44,6 +44,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 - Admin API: (`GET /api/pleroma/admin/users`) added filters user by `actor_type`
 - Pleroma API: Add `idempotency_key` to the chat message entity that can be used for optimistic message sending.
 - Pleroma API: (`GET /api/v1/pleroma/federation_status`) Add a way to get a list of unreachable instances.
+- Mastodon API: User and conversation mutes can now auto-expire if `expires_in` parameter was given while adding the mute.
 
 </details>
 
index ed7bda9ee5e9716d75980199827c143ba7ef5590..0b8a75aad2dcb0c18d552c7f6bf6f239c033f655 100644 (file)
@@ -562,7 +562,8 @@ config :pleroma, Oban,
     background: 5,
     remote_fetcher: 2,
     attachments_cleanup: 5,
-    new_users_digest: 1
+    new_users_digest: 1,
+    mute_expire: 5
   ],
   plugins: [Oban.Plugins.Pruner],
   crontab: [
index bb1000b0bd893bde927d98c1fc1d3ae76375c941..3075b6b866adb433d551d6cbc9e98901b576e2fc 100644 (file)
@@ -255,6 +255,10 @@ There is an additional `user:pleroma_chat` stream. Incoming chat messages will m
 
 For viewing remote server timelines, there are `public:remote` and `public:remote:media` streams. Each of these accept a parameter like `?instance=lain.com`.
 
+## User muting and thread muting
+
+Both user muting and thread muting can be done for only a certain time by adding an `expires_in` parameter to the API calls and giving the expiration time in seconds.
+
 ## Not implemented
 
 Pleroma is generally compatible with the Mastodon 2.7.2 API, but some newer features and non-essential features are omitted. These features usually return an HTTP 200 status code, but with an empty response. While they may be added in the future, they are considered low priority.
diff --git a/docs/administration/CLI_tasks/release_environments.md b/docs/administration/CLI_tasks/release_environments.md
deleted file mode 100644 (file)
index 36ab438..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# Generate release environment file
-
-```sh tab="OTP"
- ./bin/pleroma_ctl release_env gen
-```
-
-```sh tab="From Source"
-mix pleroma.release_env gen
-```
index b9fc4e1126cdaac01e40e5d69742068e07b6c558..75ceb65959f9288e397a70645e732edd9f2ab0fa 100644 (file)
@@ -182,7 +182,6 @@ sudo cp /opt/pleroma/installation/pleroma.service /etc/systemd/system/pleroma.se
 ```
 
 * Edit the service file and make sure that all paths fit your installation
-* Check that `EnvironmentFile` contains the correct path to the env file. Or generate the env file: `sudo -Hu pleroma mix pleroma.release_env gen`
 * Enable and start `pleroma.service`:
 
 ```shell
index 98360bcf747c77e59693d005e2d75118c010cbd8..63eda63ca230a2cb6f4b2f2035d0ecf978debffb 100644 (file)
@@ -149,9 +149,6 @@ chown -R pleroma /etc/pleroma
 # Run the config generator
 su pleroma -s $SHELL -lc "./bin/pleroma_ctl instance gen --output /etc/pleroma/config.exs --output-psql /tmp/setup_db.psql"
 
-# Run the environment file generator.
-su pleroma -s $SHELL -lc "./bin/pleroma_ctl release_env gen"
-
 # Create the postgres database
 su postgres -s $SHELL -lc "psql -f /tmp/setup_db.psql"
 
index e908cda1b318ab4bea6d6371b898b8ecb12a6667..384536f7e99d50efdb17bfe1683990efb6b1ea04 100755 (executable)
@@ -8,7 +8,6 @@ pidfile="/var/run/pleroma.pid"
 directory=/opt/pleroma
 healthcheck_delay=60
 healthcheck_timer=30
-export $(cat /opt/pleroma/config/pleroma.env)
 
 : ${pleroma_port:-4000}
 
index 63e83ed6efe27842d4867a2927fcf5c6c0aebd16..8338228d8a61616d11fddd4ceffab111f01ec104 100644 (file)
@@ -17,8 +17,6 @@ Environment="MIX_ENV=prod"
 Environment="HOME=/var/lib/pleroma"
 ; Path to the folder containing the Pleroma installation.
 WorkingDirectory=/opt/pleroma
-; Path to the environment file. the file contains RELEASE_COOKIE and etc 
-EnvironmentFile=/opt/pleroma/config/pleroma.env
 ; Path to the Mix binary.
 ExecStart=/usr/bin/mix phx.server
 
index 1915aacd9b2973092eebadd8adb708bf3d432371..fc21ae06255b88677088beb4270d6871e6a5e30c 100644 (file)
@@ -36,9 +36,7 @@ defmodule Mix.Tasks.Pleroma.Instance do
           listen_port: :string,
           strip_uploads: :string,
           anonymize_uploads: :string,
-          dedupe_uploads: :string,
-          skip_release_env: :boolean,
-          release_env_file: :string
+          dedupe_uploads: :string
         ],
         aliases: [
           o: :output,
@@ -243,24 +241,6 @@ defmodule Mix.Tasks.Pleroma.Instance do
 
       write_robots_txt(static_dir, indexable, template_dir)
 
-      if Keyword.get(options, :skip_release_env, false) do
-        shell_info("""
-        Release environment file is skip. Please generate the release env file before start.
-        `MIX_ENV=#{Mix.env()} mix pleroma.release_env gen`
-        """)
-      else
-        shell_info("Generation the environment file:")
-
-        release_env_args =
-          with path when not is_nil(path) <- Keyword.get(options, :release_env_file) do
-            ["gen", "--path", path]
-          else
-            _ -> ["gen"]
-          end
-
-        Mix.Tasks.Pleroma.ReleaseEnv.run(release_env_args)
-      end
-
       shell_info(
         "\n All files successfully written! Refer to the installation instructions for your platform for next steps."
       )
diff --git a/lib/mix/tasks/pleroma/release_env.ex b/lib/mix/tasks/pleroma/release_env.ex
deleted file mode 100644 (file)
index 9da74ff..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Mix.Tasks.Pleroma.ReleaseEnv do
-  use Mix.Task
-  import Mix.Pleroma
-
-  @shortdoc "Generate Pleroma environment file."
-  @moduledoc File.read!("docs/administration/CLI_tasks/release_environments.md")
-
-  def run(["gen" | rest]) do
-    {options, [], []} =
-      OptionParser.parse(
-        rest,
-        strict: [
-          force: :boolean,
-          path: :string
-        ],
-        aliases: [
-          p: :path,
-          f: :force
-        ]
-      )
-
-    file_path =
-      get_option(
-        options,
-        :path,
-        "Environment file path",
-        "./config/pleroma.env"
-      )
-
-    env_path = Path.expand(file_path)
-
-    proceed? =
-      if File.exists?(env_path) do
-        get_option(
-          options,
-          :force,
-          "Environment file already exists. Do you want to overwrite the #{env_path} file? (y/n)",
-          "n"
-        ) === "y"
-      else
-        true
-      end
-
-    if proceed? do
-      case do_generate(env_path) do
-        {:error, reason} ->
-          shell_error(
-            File.Error.message(%{action: "write to file", reason: reason, path: env_path})
-          )
-
-        _ ->
-          shell_info("\nThe file generated: #{env_path}.\n")
-
-          shell_info("""
-          WARNING: before start pleroma app please make sure to make the file read-only and non-modifiable.
-            Example:
-              chmod 0444 #{file_path}
-              chattr +i #{file_path}
-          """)
-      end
-    else
-      shell_info("\nThe file is exist. #{env_path}.\n")
-    end
-  end
-
-  def do_generate(path) do
-    content = "RELEASE_COOKIE=#{Base.encode32(:crypto.strong_rand_bytes(32))}"
-
-    File.mkdir_p!(Path.dirname(path))
-    File.write(path, content)
-  end
-end
index e5c9c668baef9bafc9ee6b1658481cc36faf0af7..48afe901e0d3679d013e350af3c5b533a791a0f3 100644 (file)
@@ -23,7 +23,6 @@ defmodule Pleroma.Stats do
 
   @impl true
   def init(_args) do
-    if Pleroma.Config.get(:env) == :test, do: :ok = Ecto.Adapters.SQL.Sandbox.checkout(Repo)
     {:ok, nil, {:continue, :calculate_stats}}
   end
 
@@ -32,11 +31,6 @@ defmodule Pleroma.Stats do
     GenServer.call(__MODULE__, :force_update)
   end
 
-  @doc "Performs collect stats"
-  def do_collect do
-    GenServer.cast(__MODULE__, :run_update)
-  end
-
   @doc "Returns stats data"
   @spec get_stats() :: %{
           domain_count: non_neg_integer(),
@@ -111,7 +105,11 @@ defmodule Pleroma.Stats do
   @impl true
   def handle_continue(:calculate_stats, _) do
     stats = calculate_stat_data()
-    Process.send_after(self(), :run_update, @interval)
+
+    unless Pleroma.Config.get(:env) == :test do
+      Process.send_after(self(), :run_update, @interval)
+    end
+
     {:noreply, stats}
   end
 
@@ -126,13 +124,6 @@ defmodule Pleroma.Stats do
     {:reply, state, state}
   end
 
-  @impl true
-  def handle_cast(:run_update, _state) do
-    new_stats = calculate_stat_data()
-
-    {:noreply, new_stats}
-  end
-
   @impl true
   def handle_info(:run_update, _) do
     new_stats = calculate_stat_data()
index 059d94e30f2361f3152e6502c66892f3644ad4e5..8e4ec8064a2052655776826ff2b40936363afdf1 100644 (file)
@@ -1324,14 +1324,48 @@ defmodule Pleroma.User do
     |> Repo.all()
   end
 
-  @spec mute(User.t(), User.t(), boolean()) ::
+  @spec mute(User.t(), User.t(), map()) ::
           {:ok, list(UserRelationship.t())} | {:error, String.t()}
-  def mute(%User{} = muter, %User{} = mutee, notifications? \\ true) do
-    add_to_mutes(muter, mutee, notifications?)
+  def mute(%User{} = muter, %User{} = mutee, params \\ %{}) do
+    notifications? = Map.get(params, :notifications, true)
+    expires_in = Map.get(params, :expires_in, 0)
+
+    with {:ok, user_mute} <- UserRelationship.create_mute(muter, mutee),
+         {:ok, user_notification_mute} <-
+           (notifications? && UserRelationship.create_notification_mute(muter, mutee)) ||
+             {:ok, nil} do
+      if expires_in > 0 do
+        Pleroma.Workers.MuteExpireWorker.enqueue(
+          "unmute_user",
+          %{"muter_id" => muter.id, "mutee_id" => mutee.id},
+          schedule_in: expires_in
+        )
+      end
+
+      {:ok, Enum.filter([user_mute, user_notification_mute], & &1)}
+    end
   end
 
   def unmute(%User{} = muter, %User{} = mutee) do
-    remove_from_mutes(muter, mutee)
+    with {:ok, user_mute} <- UserRelationship.delete_mute(muter, mutee),
+         {:ok, user_notification_mute} <-
+           UserRelationship.delete_notification_mute(muter, mutee) do
+      {:ok, [user_mute, user_notification_mute]}
+    end
+  end
+
+  def unmute(muter_id, mutee_id) do
+    with {:muter, %User{} = muter} <- {:muter, User.get_by_id(muter_id)},
+         {:mutee, %User{} = mutee} <- {:mutee, User.get_by_id(mutee_id)} do
+      unmute(muter, mutee)
+    else
+      {who, result} = error ->
+        Logger.warn(
+          "User.unmute/2 failed. #{who}: #{result}, muter_id: #{muter_id}, mutee_id: #{mutee_id}"
+        )
+
+        {:error, error}
+    end
   end
 
   def subscribe(%User{} = subscriber, %User{} = target) do
@@ -2320,23 +2354,6 @@ defmodule Pleroma.User do
     UserRelationship.delete_block(user, blocked)
   end
 
-  defp add_to_mutes(%User{} = user, %User{} = muted_user, notifications?) do
-    with {:ok, user_mute} <- UserRelationship.create_mute(user, muted_user),
-         {:ok, user_notification_mute} <-
-           (notifications? && UserRelationship.create_notification_mute(user, muted_user)) ||
-             {:ok, nil} do
-      {:ok, Enum.filter([user_mute, user_notification_mute], & &1)}
-    end
-  end
-
-  defp remove_from_mutes(user, %User{} = muted_user) do
-    with {:ok, user_mute} <- UserRelationship.delete_mute(user, muted_user),
-         {:ok, user_notification_mute} <-
-           UserRelationship.delete_notification_mute(user, muted_user) do
-      {:ok, [user_mute, user_notification_mute]}
-    end
-  end
-
   def set_invisible(user, invisible) do
     params = %{invisible: invisible}
 
index 4934b77885da13e5c2b673eb677ca1e616912c16..451aa2477c450852e52cdf7c802f267c84e5f6c8 100644 (file)
@@ -262,6 +262,12 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
           :query,
           %Schema{allOf: [BooleanLike], default: true},
           "Mute notifications in addition to statuses? Defaults to `true`."
+        ),
+        Operation.parameter(
+          :expires_in,
+          :query,
+          %Schema{type: :integer, default: 0},
+          "Expire the mute in `expires_in` seconds. Default 0 for infinity"
         )
       ],
       responses: %{
@@ -723,10 +729,17 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
           nullable: true,
           description: "Mute notifications in addition to statuses? Defaults to true.",
           default: true
+        },
+        expires_in: %Schema{
+          type: :integer,
+          nullable: true,
+          description: "Expire the mute in `expires_in` seconds. Default 0 for infinity",
+          default: 0
         }
       },
       example: %{
-        "notifications" => true
+        "notifications" => true,
+        "expires_in" => 86_400
       }
     }
   end
index d7ebde6f6f5c0050e73f8f4c5c3e5433c3e1b345..b3b6ceb68940784e518a0a2197e1f2022146d83c 100644 (file)
@@ -223,7 +223,27 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
       security: [%{"oAuth" => ["write:mutes"]}],
       description: "Do not receive notifications for the thread that this status is part of.",
       operationId: "StatusController.mute_conversation",
-      parameters: [id_param()],
+      requestBody:
+        request_body("Parameters", %Schema{
+          type: :object,
+          properties: %{
+            expires_in: %Schema{
+              type: :integer,
+              nullable: true,
+              description: "Expire the mute in `expires_in` seconds. Default 0 for infinity",
+              default: 0
+            }
+          }
+        }),
+      parameters: [
+        id_param(),
+        Operation.parameter(
+          :expires_in,
+          :query,
+          %Schema{type: :integer, default: 0},
+          "Expire the mute in `expires_in` seconds. Default 0 for infinity"
+        )
+      ],
       responses: %{
         200 => status_response(),
         400 => Operation.response("Error", "application/json", ApiError)
index 318ffc5d0077f7bff258fb2f95e161b7ffdd8660..0ab1b115d55270881a3e3f889e039e40434133dc 100644 (file)
@@ -454,20 +454,46 @@ defmodule Pleroma.Web.CommonAPI do
     end
   end
 
-  def add_mute(user, activity) do
+  def add_mute(user, activity, params \\ %{}) do
+    expires_in = Map.get(params, :expires_in, 0)
+
     with {:ok, _} <- ThreadMute.add_mute(user.id, activity.data["context"]),
          _ <- Pleroma.Notification.mark_context_as_read(user, activity.data["context"]) do
+      if expires_in > 0 do
+        Pleroma.Workers.MuteExpireWorker.enqueue(
+          "unmute_conversation",
+          %{"user_id" => user.id, "activity_id" => activity.id},
+          schedule_in: expires_in
+        )
+      end
+
       {:ok, activity}
     else
       {:error, _} -> {:error, dgettext("errors", "conversation is already muted")}
     end
   end
 
-  def remove_mute(user, activity) do
+  def remove_mute(%User{} = user, %Activity{} = activity) do
     ThreadMute.remove_mute(user.id, activity.data["context"])
     {:ok, activity}
   end
 
+  def remove_mute(user_id, activity_id) do
+    with {:user, %User{} = user} <- {:user, User.get_by_id(user_id)},
+         {:activity, %Activity{} = activity} <- {:activity, Activity.get_by_id(activity_id)} do
+      remove_mute(user, activity)
+    else
+      {what, result} = error ->
+        Logger.warn(
+          "CommonAPI.remove_mute/2 failed. #{what}: #{result}, user_id: #{user_id}, activity_id: #{
+            activity_id
+          }"
+        )
+
+        {:error, error}
+    end
+  end
+
   def thread_muted?(%User{id: user_id}, %{data: %{"context" => context}})
       when is_binary(context) do
     ThreadMute.exists?(user_id, context)
index 6f759d559648cc2cb9ebe34f40ce15102d6ebf9e..712991c1888d3e4deca00ac90502e47ffeb43c7e 100644 (file)
@@ -37,9 +37,11 @@ defmodule Pleroma.Web.Fallback.RedirectController do
 
     tags = build_tags(conn, params)
     preloads = preload_data(conn, params)
+    title = "<title>#{Pleroma.Config.get([:instance, :name])}</title>"
 
     response =
       index_content
+      |> String.replace(~r/<title>.+?<\/title>/, title)
       |> String.replace("<!--server-generated-meta-->", tags <> preloads)
 
     conn
@@ -54,9 +56,11 @@ defmodule Pleroma.Web.Fallback.RedirectController do
   def redirector_with_preload(conn, params) do
     {:ok, index_content} = File.read(index_file_path())
     preloads = preload_data(conn, params)
+    title = "<title>#{Pleroma.Config.get([:instance, :name])}</title>"
 
     response =
       index_content
+      |> String.replace(~r/<title>.+?<\/title>/, title)
       |> String.replace("<!--server-generated-meta-->", preloads)
 
     conn
index 1ae03e7e28d2d3651cb91a9134168e7f50beb2b9..56c024617c9cb948083ed8d8413659a0da0f6e7b 100644 (file)
@@ -83,7 +83,7 @@ defmodule Pleroma.Web.Feed.FeedView do
 
   def activity_content(_), do: ""
 
-  def activity_context(activity), do: activity.data["context"]
+  def activity_context(activity), do: escape(activity.data["context"])
 
   def attachment_href(attachment) do
     attachment["url"]
index a2715cf28a3d35dc3363714c35f0f029d45523c8..784fdc9755f832830d9e97ea257ad23661ea6388 100644 (file)
@@ -394,7 +394,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
 
   @doc "POST /api/v1/accounts/:id/mute"
   def mute(%{assigns: %{user: muter, account: muted}, body_params: params} = conn, _params) do
-    with {:ok, _user_relationships} <- User.mute(muter, muted, params.notifications) do
+    with {:ok, _user_relationships} <- User.mute(muter, muted, params) do
       render(conn, "relationship.json", user: muter, target: muted)
     else
       {:error, message} -> json_response(conn, :forbidden, %{error: message})
index 6848adace711aab8ee9b496d2eea58c4e2604181..4d9be5240c912fc03416501af38035c4261e0c46 100644 (file)
@@ -284,9 +284,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
   end
 
   @doc "POST /api/v1/statuses/:id/mute"
-  def mute_conversation(%{assigns: %{user: user}} = conn, %{id: id}) do
+  def mute_conversation(%{assigns: %{user: user}, body_params: params} = conn, %{id: id}) do
     with %Activity{} = activity <- Activity.get_by_id(id),
-         {:ok, activity} <- CommonAPI.add_mute(user, activity) do
+         {:ok, activity} <- CommonAPI.add_mute(user, activity, params) do
       try_render(conn, "show.json", activity: activity, for: user, as: :activity)
     end
   end
index 78350f2aa194c8ca311a6db733155a55027871d4..3fd150c4e7570b6d54e449a87ffac7d1adc74d7a 100644 (file)
@@ -12,7 +12,7 @@
   <link href="<%= activity_context(@activity) %>" rel="ostatus:conversation"/>
 
   <%= if @data["summary"] do %>
-    <summary><%= @data["summary"] %></summary>
+    <summary><%= escape(@data["summary"]) %></summary>
   <% end %>
 
   <%= if @activity.local do %>
index a304a16afecec2827062775909c9c97d17a4de6e..42960de7d45f58926546a23145a8d1db60ad108f 100644 (file)
@@ -12,7 +12,7 @@
   <link rel="ostatus:conversation"><%= activity_context(@activity) %></link>
 
   <%= if @data["summary"] do %>
-    <description><%= @data["summary"] %></description>
+    <description><%= escape(@data["summary"]) %></description>
   <% end %>
 
   <%= if @activity.local do %>
diff --git a/lib/pleroma/workers/mute_expire_worker.ex b/lib/pleroma/workers/mute_expire_worker.ex
new file mode 100644 (file)
index 0000000..32a12ba
--- /dev/null
@@ -0,0 +1,20 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Workers.MuteExpireWorker do
+  use Pleroma.Workers.WorkerHelper, queue: "mute_expire"
+
+  @impl Oban.Worker
+  def perform(%Job{args: %{"op" => "unmute_user", "muter_id" => muter_id, "mutee_id" => mutee_id}}) do
+    Pleroma.User.unmute(muter_id, mutee_id)
+    :ok
+  end
+
+  def perform(%Job{
+        args: %{"op" => "unmute_conversation", "user_id" => user_id, "activity_id" => activity_id}
+      }) do
+    Pleroma.Web.CommonAPI.remove_mute(user_id, activity_id)
+    :ok
+  end
+end
index fe69a2def027b752dd0f44c9394c647658fac8bf..8a02710ee2b336e7aed49b167de6217c711c6500 100644 (file)
@@ -5,8 +5,6 @@
 defmodule Mix.Tasks.Pleroma.InstanceTest do
   use ExUnit.Case
 
-  @release_env_file "./test/pleroma.test.env"
-
   setup do
     File.mkdir_p!(tmp_path())
 
@@ -18,8 +16,6 @@ defmodule Mix.Tasks.Pleroma.InstanceTest do
         File.rm_rf(Path.join(static_dir, "robots.txt"))
       end
 
-      if File.exists?(@release_env_file), do: File.rm_rf(@release_env_file)
-
       Pleroma.Config.put([:instance, :static_dir], static_dir)
     end)
 
@@ -73,9 +69,7 @@ defmodule Mix.Tasks.Pleroma.InstanceTest do
         "--dedupe-uploads",
         "n",
         "--anonymize-uploads",
-        "n",
-        "--release-env-file",
-        @release_env_file
+        "n"
       ])
     end
 
@@ -97,9 +91,6 @@ defmodule Mix.Tasks.Pleroma.InstanceTest do
     assert generated_config =~ "filters: [Pleroma.Upload.Filter.ExifTool]"
     assert File.read!(tmp_path() <> "setup.psql") == generated_setup_psql()
     assert File.exists?(Path.expand("./test/instance/static/robots.txt"))
-    assert File.exists?(@release_env_file)
-
-    assert File.read!(@release_env_file) =~ ~r/^RELEASE_COOKIE=.*/
   end
 
   defp generated_setup_psql do
diff --git a/test/mix/tasks/pleroma/release_env_test.exs b/test/mix/tasks/pleroma/release_env_test.exs
deleted file mode 100644 (file)
index 519f1eb..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Mix.Tasks.Pleroma.ReleaseEnvTest do
-  use ExUnit.Case
-  import ExUnit.CaptureIO, only: [capture_io: 1]
-
-  @path "config/pleroma.test.env"
-
-  def do_clean do
-    if File.exists?(@path) do
-      File.rm_rf(@path)
-    end
-  end
-
-  setup do
-    do_clean()
-    on_exit(fn -> do_clean() end)
-    :ok
-  end
-
-  test "generate pleroma.env" do
-    assert capture_io(fn ->
-             Mix.Tasks.Pleroma.ReleaseEnv.run(["gen", "--path", @path, "--force"])
-           end) =~ "The file generated"
-
-    assert File.read!(@path) =~ "RELEASE_COOKIE="
-  end
-end
index a74fb7bc2cc86812792ff5ba7360775a52d0a7a8..92c0bc8b69fc69371e234b3ed84d7b38a3308100 100644 (file)
@@ -229,7 +229,7 @@ defmodule Pleroma.NotificationTest do
       muter = insert(:user)
       muted = insert(:user)
 
-      {:ok, _user_relationships} = User.mute(muter, muted, false)
+      {:ok, _user_relationships} = User.mute(muter, muted, %{notifications: false})
 
       {:ok, activity} = CommonAPI.post(muted, %{status: "Hi @#{muter.nickname}"})
 
@@ -1015,7 +1015,7 @@ defmodule Pleroma.NotificationTest do
 
     test "it returns notifications for muted user without notifications", %{user: user} do
       muted = insert(:user)
-      {:ok, _user_relationships} = User.mute(user, muted, false)
+      {:ok, _user_relationships} = User.mute(user, muted, %{notifications: false})
 
       {:ok, _activity} = CommonAPI.post(muted, %{status: "hey @#{user.nickname}"})
 
index 9ae52d594e0d961a7afc39d0c1834730a2b861b9..c678dadb3075ba0e092156beee902a4037702c66 100644 (file)
@@ -1008,6 +1008,27 @@ defmodule Pleroma.UserTest do
       assert User.muted_notifications?(user, muted_user)
     end
 
+    test "expiring" do
+      user = insert(:user)
+      muted_user = insert(:user)
+
+      {:ok, _user_relationships} = User.mute(user, muted_user, %{expires_in: 60})
+      assert User.mutes?(user, muted_user)
+
+      worker = Pleroma.Workers.MuteExpireWorker
+      args = %{"op" => "unmute_user", "muter_id" => user.id, "mutee_id" => muted_user.id}
+
+      assert_enqueued(
+        worker: worker,
+        args: args
+      )
+
+      assert :ok = perform_job(worker, args)
+
+      refute User.mutes?(user, muted_user)
+      refute User.muted_notifications?(user, muted_user)
+    end
+
     test "it unmutes users" do
       user = insert(:user)
       muted_user = insert(:user)
@@ -1019,6 +1040,17 @@ defmodule Pleroma.UserTest do
       refute User.muted_notifications?(user, muted_user)
     end
 
+    test "it unmutes users by id" do
+      user = insert(:user)
+      muted_user = insert(:user)
+
+      {:ok, _user_relationships} = User.mute(user, muted_user)
+      {:ok, _user_mute} = User.unmute(user.id, muted_user.id)
+
+      refute User.mutes?(user, muted_user)
+      refute User.muted_notifications?(user, muted_user)
+    end
+
     test "it mutes user without notifications" do
       user = insert(:user)
       muted_user = insert(:user)
@@ -1026,7 +1058,7 @@ defmodule Pleroma.UserTest do
       refute User.mutes?(user, muted_user)
       refute User.muted_notifications?(user, muted_user)
 
-      {:ok, _user_relationships} = User.mute(user, muted_user, false)
+      {:ok, _user_relationships} = User.mute(user, muted_user, %{notifications: false})
 
       assert User.mutes?(user, muted_user)
       refute User.muted_notifications?(user, muted_user)
index c5b90ad84297b7d569eac29dd92069a6f9125328..8e87e69fe0a3b4f84ab70a52d3eb95950d03e5d7 100644 (file)
@@ -3,8 +3,8 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.CommonAPITest do
-  use Pleroma.DataCase
   use Oban.Testing, repo: Pleroma.Repo
+  use Pleroma.DataCase
 
   alias Pleroma.Activity
   alias Pleroma.Chat
@@ -922,12 +922,34 @@ defmodule Pleroma.Web.CommonAPITest do
       assert CommonAPI.thread_muted?(user, activity)
     end
 
+    test "add expiring mute", %{user: user, activity: activity} do
+      {:ok, _} = CommonAPI.add_mute(user, activity, %{expires_in: 60})
+      assert CommonAPI.thread_muted?(user, activity)
+
+      worker = Pleroma.Workers.MuteExpireWorker
+      args = %{"op" => "unmute_conversation", "user_id" => user.id, "activity_id" => activity.id}
+
+      assert_enqueued(
+        worker: worker,
+        args: args
+      )
+
+      assert :ok = perform_job(worker, args)
+      refute CommonAPI.thread_muted?(user, activity)
+    end
+
     test "remove mute", %{user: user, activity: activity} do
       CommonAPI.add_mute(user, activity)
       {:ok, _} = CommonAPI.remove_mute(user, activity)
       refute CommonAPI.thread_muted?(user, activity)
     end
 
+    test "remove mute by ids", %{user: user, activity: activity} do
+      CommonAPI.add_mute(user, activity)
+      {:ok, _} = CommonAPI.remove_mute(user.id, activity.id)
+      refute CommonAPI.thread_muted?(user, activity)
+    end
+
     test "check that mutes can't be duplicate", %{user: user, activity: activity} do
       CommonAPI.add_mute(user, activity)
       {:error, _} = CommonAPI.add_mute(user, activity)
index eabfe3a6383449a008b19796950f0f9eca193b4e..16f00271704fee1e19999a5179025c38ab5805e9 100644 (file)
@@ -12,16 +12,17 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
   alias Pleroma.Object
   alias Pleroma.User
   alias Pleroma.Web.CommonAPI
+  alias Pleroma.Web.Feed.FeedView
 
   setup do: clear_config([:static_fe, :enabled], false)
 
   describe "feed" do
     setup do: clear_config([:feed])
 
-    test "gets an atom feed", %{conn: conn} do
+    setup do
       Config.put(
         [:feed, :post_title],
-        %{max_length: 10, omission: "..."}
+        %{max_length: 15, omission: "..."}
       )
 
       activity = insert(:note_activity)
@@ -29,7 +30,8 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
       note =
         insert(:note,
           data: %{
-            "content" => "This is :moominmamma: note ",
+            "content" => "This & this is :moominmamma: note ",
+            "source" => "This & this is :moominmamma: note ",
             "attachment" => [
               %{
                 "url" => [
@@ -37,7 +39,9 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
                 ]
               }
             ],
-            "inReplyTo" => activity.data["id"]
+            "inReplyTo" => activity.data["id"],
+            "context" => "2hu & as",
+            "summary" => "2hu & as"
           }
         )
 
@@ -48,7 +52,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
         insert(:note,
           user: user,
           data: %{
-            "content" => "42 This is :moominmamma: note ",
+            "content" => "42 This is :moominmamma: note ",
             "inReplyTo" => activity.data["id"]
           }
         )
@@ -56,6 +60,10 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
       note_activity2 = insert(:note_activity, note: note2)
       object = Object.normalize(note_activity)
 
+      [user: user, object: object, max_id: note_activity2.id]
+    end
+
+    test "gets an atom feed", %{conn: conn, user: user, object: object, max_id: max_id} do
       resp =
         conn
         |> put_req_header("accept", "application/atom+xml")
@@ -67,13 +75,15 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
         |> SweetXml.parse()
         |> SweetXml.xpath(~x"//entry/title/text()"l)
 
-      assert activity_titles == ['42 This...', 'This is...']
-      assert resp =~ object.data["content"]
+      assert activity_titles == ['42 &amp; Thi...', 'This &amp; t...']
+      assert resp =~ FeedView.escape(object.data["content"])
+      assert resp =~ FeedView.escape(object.data["summary"])
+      assert resp =~ FeedView.escape(object.data["context"])
 
       resp =
         conn
         |> put_req_header("accept", "application/atom+xml")
-        |> get("/users/#{user.nickname}/feed", %{"max_id" => note_activity2.id})
+        |> get("/users/#{user.nickname}/feed", %{"max_id" => max_id})
         |> response(200)
 
       activity_titles =
@@ -81,47 +91,10 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
         |> SweetXml.parse()
         |> SweetXml.xpath(~x"//entry/title/text()"l)
 
-      assert activity_titles == ['This is...']
+      assert activity_titles == ['This &amp; t...']
     end
 
-    test "gets a rss feed", %{conn: conn} do
-      Pleroma.Config.put(
-        [:feed, :post_title],
-        %{max_length: 10, omission: "..."}
-      )
-
-      activity = insert(:note_activity)
-
-      note =
-        insert(:note,
-          data: %{
-            "content" => "This is :moominmamma: note ",
-            "attachment" => [
-              %{
-                "url" => [
-                  %{"mediaType" => "image/png", "href" => "https://pleroma.gov/image.png"}
-                ]
-              }
-            ],
-            "inReplyTo" => activity.data["id"]
-          }
-        )
-
-      note_activity = insert(:note_activity, note: note)
-      user = User.get_cached_by_ap_id(note_activity.data["actor"])
-
-      note2 =
-        insert(:note,
-          user: user,
-          data: %{
-            "content" => "42 This is :moominmamma: note ",
-            "inReplyTo" => activity.data["id"]
-          }
-        )
-
-      note_activity2 = insert(:note_activity, note: note2)
-      object = Object.normalize(note_activity)
-
+    test "gets a rss feed", %{conn: conn, user: user, object: object, max_id: max_id} do
       resp =
         conn
         |> put_req_header("accept", "application/rss+xml")
@@ -133,13 +106,15 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
         |> SweetXml.parse()
         |> SweetXml.xpath(~x"//item/title/text()"l)
 
-      assert activity_titles == ['42 This...', 'This is...']
-      assert resp =~ object.data["content"]
+      assert activity_titles == ['42 &amp; Thi...', 'This &amp; t...']
+      assert resp =~ FeedView.escape(object.data["content"])
+      assert resp =~ FeedView.escape(object.data["summary"])
+      assert resp =~ FeedView.escape(object.data["context"])
 
       resp =
         conn
         |> put_req_header("accept", "application/rss+xml")
-        |> get("/users/#{user.nickname}/feed.rss", %{"max_id" => note_activity2.id})
+        |> get("/users/#{user.nickname}/feed.rss", %{"max_id" => max_id})
         |> response(200)
 
       activity_titles =
@@ -147,7 +122,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
         |> SweetXml.parse()
         |> SweetXml.xpath(~x"//item/title/text()"l)
 
-      assert activity_titles == ['This is...']
+      assert activity_titles == ['This &amp; t...']
     end
 
     test "returns 404 for a missing feed", %{conn: conn} do
index 70ef0e8b5012aa9a15f7fe1fab7fc39015f325f7..5fd518c602c6e1e8ae626175238b4c20eb21589f 100644 (file)
@@ -502,7 +502,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
 
     assert length(json_response_and_validate_schema(ret_conn, 200)) == 1
 
-    {:ok, _user_relationships} = User.mute(user, user2, false)
+    {:ok, _user_relationships} = User.mute(user, user2, %{notifications: false})
 
     conn = get(conn, "/api/v1/notifications")
 
index 203e61c716a74fa38512cca633c32219f3d70e94..139e32362104907bcb49b38a651c33d7ac3c1281 100644 (file)
@@ -277,7 +277,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
       {:ok, user} = User.follow(user, other_user)
       {:ok, other_user} = User.follow(other_user, user)
       {:ok, _subscription} = User.subscribe(user, other_user)
-      {:ok, _user_relationships} = User.mute(user, other_user, true)
+      {:ok, _user_relationships} = User.mute(user, other_user, %{notifications: true})
       {:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, other_user)
 
       expected =