Refactor as per Rin's suggestions, add endpoint tests

This commit is contained in:
Karen Konou 2019-02-11 11:59:51 +01:00
parent cc21fc5f53
commit c01ef574c1
9 changed files with 136 additions and 105 deletions

View file

@ -6,7 +6,7 @@ defmodule Pleroma.Notification do
use Ecto.Schema use Ecto.Schema
alias Pleroma.{User, Activity, Notification, Repo} alias Pleroma.{User, Activity, Notification, Repo}
alias Pleroma.Web.CommonAPI.Utils alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Web.ThreadMute alias Pleroma.Web.CommonAPI
import Ecto.Query import Ecto.Query
schema "notifications" do schema "notifications" do
@ -113,7 +113,7 @@ def create_notifications(_), do: {:ok, []}
# TODO move to sql, too. # TODO move to sql, too.
def create_notification(%Activity{} = activity, %User{} = user) do def create_notification(%Activity{} = activity, %User{} = user) do
unless User.blocks?(user, %{ap_id: activity.data["actor"]}) or unless User.blocks?(user, %{ap_id: activity.data["actor"]}) or
ThreadMute.muted?(user, activity) or user.ap_id == activity.data["actor"] or CommonAPI.thread_muted?(user, activity) or user.ap_id == activity.data["actor"] or
(activity.data["type"] == "Follow" and (activity.data["type"] == "Follow" and
Enum.any?(Notification.for_user(user), fn notif -> Enum.any?(Notification.for_user(user), fn notif ->
notif.activity.data["type"] == "Follow" and notif.activity.data["type"] == "Follow" and

View file

@ -0,0 +1,45 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.ThreadMute do
use Ecto.Schema
alias Pleroma.{Repo, User, ThreadMute}
require Ecto.Query
schema "thread_mutes" do
belongs_to(:user, User, type: Pleroma.FlakeId)
field(:context, :string)
end
def changeset(mute, params \\ %{}) do
mute
|> Ecto.Changeset.cast(params, [:user_id, :context])
|> Ecto.Changeset.foreign_key_constraint(:user_id)
|> Ecto.Changeset.unique_constraint(:user_id, name: :unique_index)
end
def query(user_id, context) do
user_id = Pleroma.FlakeId.from_string(user_id)
ThreadMute
|> Ecto.Query.where(user_id: ^user_id)
|> Ecto.Query.where(context: ^context)
end
def add_mute(user_id, context) do
%ThreadMute{}
|> changeset(%{user_id: user_id, context: context})
|> Repo.insert()
end
def remove_mute(user_id, context) do
query(user_id, context)
|> Repo.delete_all()
end
def check_muted(user_id, context) do
query(user_id, context)
|> Repo.all()
end
end

View file

@ -3,7 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.CommonAPI do defmodule Pleroma.Web.CommonAPI do
alias Pleroma.{User, Repo, Activity, Object} alias Pleroma.{User, Repo, Activity, Object, ThreadMute}
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Formatter alias Pleroma.Formatter
@ -216,4 +216,27 @@ def unpin(id_or_ap_id, user) do
{:error, "Could not unpin"} {:error, "Could not unpin"}
end end
end end
def add_mute(user, activity) do
with {:ok, _} <- ThreadMute.add_mute(user.id, activity.data["context"]) do
{:ok, activity}
else
{:error, _} -> {:error, "conversation is already muted"}
end
end
def remove_mute(user, activity) do
ThreadMute.remove_mute(user.id, activity.data["context"])
{:ok, activity}
end
def thread_muted?(%{id: nil} = _user, _activity), do: false
def thread_muted?(user, activity) do
with [] <- ThreadMute.check_muted(user.id, activity.data["context"]) do
false
else
_ -> true
end
end
end end

View file

@ -446,7 +446,8 @@ def unbookmark_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
end end
def mute_conversation(%{assigns: %{user: user}} = conn, %{"id" => id}) do def mute_conversation(%{assigns: %{user: user}} = conn, %{"id" => id}) do
with {:ok, activity} <- Pleroma.Web.ThreadMute.add_mute(user, id) do activity = Activity.get_by_id(id)
with {:ok, activity} <- CommonAPI.add_mute(user, activity) do
conn conn
|> put_view(StatusView) |> put_view(StatusView)
|> try_render("status.json", %{activity: activity, for: user, as: :activity}) |> try_render("status.json", %{activity: activity, for: user, as: :activity})
@ -459,7 +460,8 @@ def mute_conversation(%{assigns: %{user: user}} = conn, %{"id" => id}) do
end end
def unmute_conversation(%{assigns: %{user: user}} = conn, %{"id" => id}) do def unmute_conversation(%{assigns: %{user: user}} = conn, %{"id" => id}) do
with {:ok, activity} <- Pleroma.Web.ThreadMute.remove_mute(user, id) do activity = Activity.get_by_id(id)
with {:ok, activity} <- CommonAPI.remove_mute(user, activity) do
conn conn
|> put_view(StatusView) |> put_view(StatusView)
|> try_render("status.json", %{activity: activity, for: user, as: :activity}) |> try_render("status.json", %{activity: activity, for: user, as: :activity})

View file

@ -9,6 +9,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
alias Pleroma.HTML alias Pleroma.HTML
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.CommonAPI.Utils alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Web.MediaProxy alias Pleroma.Web.MediaProxy
alias Pleroma.Web.MastodonAPI.AccountView alias Pleroma.Web.MastodonAPI.AccountView
@ -160,7 +161,7 @@ def render("status.json", %{activity: %{data: %{"object" => object}} = activity}
reblogged: present?(repeated), reblogged: present?(repeated),
favourited: present?(favorited), favourited: present?(favorited),
bookmarked: present?(bookmarked), bookmarked: present?(bookmarked),
muted: Pleroma.Web.ThreadMute.muted?(user, activity), muted: CommonAPI.thread_muted?(user, activity),
pinned: pinned?(activity, user), pinned: pinned?(activity, user),
sensitive: sensitive, sensitive: sensitive,
spoiler_text: object["summary"] || "", spoiler_text: object["summary"] || "",

View file

@ -1,62 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ThreadMute do
use Ecto.Schema
alias Pleroma.Web.ThreadMute
alias Pleroma.{Activity, Repo, User}
require Ecto.Query
schema "thread_mutes" do
belongs_to(:user, User, type: Pleroma.FlakeId)
field(:context, :string)
end
def changeset(mute, params \\ %{}) do
mute
|> Ecto.Changeset.cast(params, [:user_id, :context])
|> Ecto.Changeset.foreign_key_constraint(:user_id)
|> Ecto.Changeset.unique_constraint(:user_id, name: :unique_index)
end
def query(user, context) do
user_id = Pleroma.FlakeId.from_string(user.id)
ThreadMute
|> Ecto.Query.where(user_id: ^user_id)
|> Ecto.Query.where(context: ^context)
end
def add_mute(user, id) do
activity = Activity.get_by_id(id)
with changeset <-
changeset(%ThreadMute{}, %{user_id: user.id, context: activity.data["context"]}),
{:ok, _} <- Repo.insert(changeset) do
{:ok, activity}
else
{:error, _} -> {:error, "conversation is already muted"}
end
end
def remove_mute(user, id) do
activity = Activity.get_by_id(id)
query(user, activity.data["context"])
|> Repo.delete_all()
{:ok, activity}
end
def muted?(%{id: nil} = _user, _), do: false
def muted?(user, activity) do
with query <- query(user, activity.data["context"]),
[] <- Repo.all(query) do
false
else
_ -> true
end
end
end

View file

@ -164,4 +164,30 @@ test "should unpin when deleting a status", %{user: user, activity: activity} do
assert %User{info: %{pinned_activities: []}} = user assert %User{info: %{pinned_activities: []}} = user
end end
end end
describe "mute tests" do
setup do
user = insert(:user)
activity = insert(:note_activity)
[user: user, activity: activity]
end
test "add mute", %{user: user, activity: activity} do
{:ok, _} = CommonAPI.add_mute(user, activity)
assert 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 "check that mutes can't be duplicate", %{user: user, activity: activity} do
CommonAPI.add_mute(user, activity)
{:error, _} = CommonAPI.add_mute(user, activity)
end
end
end end

View file

@ -1749,4 +1749,37 @@ test "bookmarks" do
assert [json_response(response2, 200)] == json_response(bookmarks, 200) assert [json_response(response2, 200)] == json_response(bookmarks, 200)
end end
describe "conversation muting" do
setup do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{"status" => "HIE"})
[user: user, activity: activity]
end
test "mute conversation", %{conn: conn, user: user, activity: activity} do
id_str = to_string(activity.id)
assert %{"id" => ^id_str, "muted" => true} =
conn
|> assign(:user, user)
|> post("/api/v1/statuses/#{activity.id}/mute")
|> json_response(200)
end
test "unmute conversation", %{conn: conn, user: user, activity: activity} do
{:ok, _} = CommonAPI.add_mute(user, activity)
id_str = to_string(activity.id)
user = refresh_record(user)
assert %{"id" => ^id_str, "muted" => false} =
conn
|> assign(:user, user)
|> post("/api/v1/statuses/#{activity.id}/unmute")
|> json_response(200)
end
end
end end

View file

@ -1,37 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ThreadMuteTest do
use Pleroma.DataCase
import Pleroma.Web.ThreadMute
import Pleroma.Factory
describe "mute tests" do
setup do
user = insert(:user)
activity = insert(:note_activity)
[user: user, activity: activity]
end
test "add mute", %{user: user, activity: activity} do
{:ok, _activity} = add_mute(user, activity.id)
assert muted?(user, activity)
end
test "remove mute", %{user: user, activity: activity} do
add_mute(user, activity.id)
{:ok, _activity} = remove_mute(user, activity.id)
refute muted?(user, activity)
end
test "check that mutes can't be duplicate", %{user: user, activity: activity} do
add_mute(user, activity.id)
assert muted?(user, activity)
{:error, _} = add_mute(user, activity.id)
end
end
end