From: kaniini Date: Fri, 25 Jan 2019 05:19:32 +0000 (+0000) Subject: Merge branch 'fix/tusky-dm' into 'develop' X-Git-Url: http://git.squeep.com/?a=commitdiff_plain;h=4c99b6d35abe2beb184a12f7cba6f84a0fc6a27a;hp=-c;p=akkoma Merge branch 'fix/tusky-dm' into 'develop' Add actor to recipients list Closes #390 See merge request pleroma/pleroma!683 --- 4c99b6d35abe2beb184a12f7cba6f84a0fc6a27a diff --combined lib/pleroma/notification.ex index 2c8f60f19,4659e14ef..e47145601 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@@ -4,13 -4,14 +4,14 @@@ defmodule Pleroma.Notification do use Ecto.Schema - alias Pleroma.{User, Activity, Notification, Repo, Object} + alias Pleroma.{User, Activity, Notification, Repo} + alias Pleroma.Web.CommonAPI.Utils import Ecto.Query schema "notifications" do field(:seen, :boolean, default: false) - belongs_to(:user, Pleroma.User) - belongs_to(:activity, Pleroma.Activity) + belongs_to(:user, User, type: Pleroma.FlakeId) + belongs_to(:activity, Activity, type: Pleroma.FlakeId) timestamps() end @@@ -96,7 -97,7 +97,7 @@@ end end - def create_notifications(%Activity{id: _, data: %{"to" => _, "type" => type}} = activity) + def create_notifications(%Activity{data: %{"to" => _, "type" => type}} = activity) when type in ["Create", "Like", "Announce", "Follow"] do users = get_notified_from_activity(activity) @@@ -132,54 -133,12 +133,12 @@@ when type in ["Create", "Like", "Announce", "Follow"] do recipients = [] - |> maybe_notify_to_recipients(activity) - |> maybe_notify_mentioned_recipients(activity) + |> Utils.maybe_notify_to_recipients(activity) + |> Utils.maybe_notify_mentioned_recipients(activity) |> Enum.uniq() User.get_users_from_set(recipients, local_only) end def get_notified_from_activity(_, _local_only), do: [] - - defp maybe_notify_to_recipients( - recipients, - %Activity{data: %{"to" => to, "type" => _type}} = _activity - ) do - recipients ++ to - end - - defp maybe_notify_mentioned_recipients( - recipients, - %Activity{data: %{"to" => _to, "type" => type} = data} = _activity - ) - when type == "Create" do - object = Object.normalize(data["object"]) - - object_data = - cond do - !is_nil(object) -> - object.data - - is_map(data["object"]) -> - data["object"] - - true -> - %{} - end - - tagged_mentions = maybe_extract_mentions(object_data) - - recipients ++ tagged_mentions - end - - defp maybe_notify_mentioned_recipients(recipients, _), do: recipients - - defp maybe_extract_mentions(%{"tag" => tag}) do - tag - |> Enum.filter(fn x -> is_map(x) end) - |> Enum.filter(fn x -> x["type"] == "Mention" end) - |> Enum.map(fn x -> x["href"] end) - end - - defp maybe_extract_mentions(_), do: [] end diff --combined lib/pleroma/web/activity_pub/activity_pub.ex index 85fa83e2b,487d4c84a..6b4682e35 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@@ -36,6 -36,14 +36,14 @@@ defmodule Pleroma.Web.ActivityPub.Activ {recipients, to, cc} end + defp get_recipients(%{"type" => "Create"} = data) do + to = data["to"] || [] + cc = data["cc"] || [] + actor = data["actor"] || [] + recipients = (to ++ cc ++ [actor]) |> Enum.uniq() + {recipients, to, cc} + end + defp get_recipients(data) do to = data["to"] || [] cc = data["cc"] || [] @@@ -92,7 -100,7 +100,7 @@@ def stream_out(activity) do public = "https://www.w3.org/ns/activitystreams#Public" - if activity.data["type"] in ["Create", "Announce"] do + if activity.data["type"] in ["Create", "Announce", "Delete"] do Pleroma.Web.Streamer.stream("user", activity) Pleroma.Web.Streamer.stream("list", activity) @@@ -103,18 -111,16 +111,18 @@@ Pleroma.Web.Streamer.stream("public:local", activity) end - activity.data["object"] - |> Map.get("tag", []) - |> Enum.filter(fn tag -> is_bitstring(tag) end) - |> Enum.map(fn tag -> Pleroma.Web.Streamer.stream("hashtag:" <> tag, activity) end) + if activity.data["type"] in ["Create"] do + activity.data["object"] + |> Map.get("tag", []) + |> Enum.filter(fn tag -> is_bitstring(tag) end) + |> Enum.map(fn tag -> Pleroma.Web.Streamer.stream("hashtag:" <> tag, activity) end) - if activity.data["object"]["attachment"] != [] do - Pleroma.Web.Streamer.stream("public:media", activity) + if activity.data["object"]["attachment"] != [] do + Pleroma.Web.Streamer.stream("public:media", activity) - if activity.local do - Pleroma.Web.Streamer.stream("public:local:media", activity) + if activity.local do + Pleroma.Web.Streamer.stream("public:local:media", activity) + end end end else @@@ -140,9 -146,8 +148,9 @@@ additional ), {:ok, activity} <- insert(create_data, local), - :ok <- maybe_federate(activity), - {:ok, _actor} <- User.increase_note_count(actor) do + # Changing note count prior to enqueuing federation task in order to avoid race conditions on updating user.info + {:ok, _actor} <- User.increase_note_count(actor), + :ok <- maybe_federate(activity) do {:ok, activity} end end @@@ -227,11 -232,10 +235,11 @@@ %User{ap_id: _} = user, %Object{data: %{"id" => _}} = object, activity_id \\ nil, - local \\ true + local \\ true, + public \\ true ) do with true <- is_public?(object), - announce_data <- make_announce_data(user, object, activity_id), + announce_data <- make_announce_data(user, object, activity_id, public), {:ok, activity} <- insert(announce_data, local), {:ok, object} <- add_announce_to_object(activity, object), :ok <- maybe_federate(activity) do @@@ -289,9 -293,8 +297,9 @@@ with {:ok, _} <- Object.delete(object), {:ok, activity} <- insert(data, local), - :ok <- maybe_federate(activity), - {:ok, _actor} <- User.decrease_note_count(user) do + # Changing note count prior to enqueuing federation task in order to avoid race conditions on updating user.info + {:ok, _actor} <- User.decrease_note_count(user), + :ok <- maybe_federate(activity) do {:ok, activity} end end @@@ -410,8 -413,6 +418,8 @@@ |> Enum.reverse() end + defp restrict_since(query, %{"since_id" => ""}), do: query + defp restrict_since(query, %{"since_id" => since_id}) do from(activity in query, where: activity.id > ^since_id) end @@@ -467,8 -468,6 +475,8 @@@ defp restrict_local(query, _), do: query + defp restrict_max(query, %{"max_id" => ""}), do: query + defp restrict_max(query, %{"max_id" => max_id}) do from(activity in query, where: activity.id < ^max_id) end @@@ -805,24 -804,13 +813,24 @@@ end end - def is_public?(%Object{data: %{"type" => "Tombstone"}}) do - false + def is_public?(%Object{data: %{"type" => "Tombstone"}}), do: false + def is_public?(%Object{data: data}), do: is_public?(data) + def is_public?(%Activity{data: data}), do: is_public?(data) + def is_public?(%{"directMessage" => true}), do: false + + def is_public?(data) do + "https://www.w3.org/ns/activitystreams#Public" in (data["to"] ++ (data["cc"] || [])) + end + + def is_private?(activity) do + !is_public?(activity) && Enum.any?(activity.data["to"], &String.contains?(&1, "/followers")) end - def is_public?(activity) do - "https://www.w3.org/ns/activitystreams#Public" in (activity.data["to"] ++ - (activity.data["cc"] || [])) + def is_direct?(%Activity{data: %{"directMessage" => true}}), do: true + def is_direct?(%Object{data: %{"directMessage" => true}}), do: true + + def is_direct?(activity) do + !is_public?(activity) && !is_private?(activity) end def visible_for_user?(activity, nil) do diff --combined lib/pleroma/web/common_api/utils.ex index a0f59d900,d36875705..208677bd7 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@@ -14,13 -14,13 +14,13 @@@ defmodule Pleroma.Web.CommonAPI.Utils d # This is a hack for twidere. def get_by_id_or_ap_id(id) do - activity = Repo.get(Activity, id) || Activity.get_create_activity_by_object_ap_id(id) + activity = Repo.get(Activity, id) || Activity.get_create_by_object_ap_id(id) activity && if activity.data["type"] == "Create" do activity else - Activity.get_create_activity_by_object_ap_id(activity.data["object"]) + Activity.get_create_by_object_ap_id(activity.data["object"]) end end @@@ -116,18 -116,16 +116,18 @@@ Enum.join([text | attachment_text], "
") end + def format_input(text, mentions, tags, format, options \\ []) + @doc """ Formatting text to plain text. """ - def format_input(text, mentions, tags, "text/plain") do + def format_input(text, mentions, tags, "text/plain", options) do text |> Formatter.html_escape("text/plain") |> String.replace(~r/\r?\n/, "
") |> (&{[], &1}).() |> Formatter.add_links() - |> Formatter.add_user_links(mentions) + |> Formatter.add_user_links(mentions, options[:user_links] || []) |> Formatter.add_hashtag_links(tags) |> Formatter.finalize() end @@@ -135,24 -133,24 +135,24 @@@ @doc """ Formatting text to html. """ - def format_input(text, mentions, _tags, "text/html") do + def format_input(text, mentions, _tags, "text/html", options) do text |> Formatter.html_escape("text/html") |> (&{[], &1}).() - |> Formatter.add_user_links(mentions) + |> Formatter.add_user_links(mentions, options[:user_links] || []) |> Formatter.finalize() end @doc """ Formatting text to markdown. """ - def format_input(text, mentions, tags, "text/markdown") do + def format_input(text, mentions, tags, "text/markdown", options) do text |> Formatter.mentions_escape(mentions) |> Earmark.as_html!() |> Formatter.html_escape("text/html") |> (&{[], &1}).() - |> Formatter.add_user_links(mentions) + |> Formatter.add_user_links(mentions, options[:user_links] || []) |> Formatter.add_hashtag_links(tags) |> Formatter.finalize() end @@@ -261,4 -259,46 +261,46 @@@ } end) end + + def maybe_notify_to_recipients( + recipients, + %Activity{data: %{"to" => to, "type" => _type}} = _activity + ) do + recipients ++ to + end + + def maybe_notify_mentioned_recipients( + recipients, + %Activity{data: %{"to" => _to, "type" => type} = data} = _activity + ) + when type == "Create" do + object = Object.normalize(data["object"]) + + object_data = + cond do + !is_nil(object) -> + object.data + + is_map(data["object"]) -> + data["object"] + + true -> + %{} + end + + tagged_mentions = maybe_extract_mentions(object_data) + + recipients ++ tagged_mentions + end + + def maybe_notify_mentioned_recipients(recipients, _), do: recipients + + def maybe_extract_mentions(%{"tag" => tag}) do + tag + |> Enum.filter(fn x -> is_map(x) end) + |> Enum.filter(fn x -> x["type"] == "Mention" end) + |> Enum.map(fn x -> x["href"] end) + end + + def maybe_extract_mentions(_), do: [] end diff --combined lib/pleroma/web/twitter_api/views/activity_view.ex index 5eb06a26e,9ae7846c0..e0a52d94a --- a/lib/pleroma/web/twitter_api/views/activity_view.ex +++ b/lib/pleroma/web/twitter_api/views/activity_view.ex @@@ -101,10 -101,20 +101,10 @@@ defmodule Pleroma.Web.TwitterAPI.Activi user true -> - error_user(ap_id) + User.error_user(ap_id) end end - defp error_user(ap_id) do - %User{ - name: ap_id, - ap_id: ap_id, - info: %User.Info{}, - nickname: "erroruser@example.com", - inserted_at: NaiveDateTime.utc_now() - } - end - def render("index.json", opts) do context_ids = collect_context_ids(opts.activities) users = collect_users(opts.activities) @@@ -168,7 -178,7 +168,7 @@@ def render("activity.json", %{activity: %{data: %{"type" => "Announce"}} = activity} = opts) do user = get_user(activity.data["actor"], opts) created_at = activity.data["published"] |> Utils.date_to_asctime() - announced_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"]) + announced_activity = Activity.get_create_by_object_ap_id(activity.data["object"]) text = "#{user.nickname} retweeted a status." @@@ -192,7 -202,7 +192,7 @@@ def render("activity.json", %{activity: %{data: %{"type" => "Like"}} = activity} = opts) do user = get_user(activity.data["actor"], opts) - liked_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"]) + liked_activity = Activity.get_create_by_object_ap_id(activity.data["object"]) liked_activity_id = if liked_activity, do: liked_activity.id, else: nil created_at = @@@ -236,7 -246,9 +236,9 @@@ pinned = activity.id in user.info.pinned_activities attentions = - activity.recipients + [] + |> Utils.maybe_notify_to_recipients(activity) + |> Utils.maybe_notify_mentioned_recipients(activity) |> Enum.map(fn ap_id -> get_user(ap_id, opts) end) |> Enum.filter(& &1) |> Enum.map(fn user -> UserView.render("show.json", %{user: user, for: opts[:for]}) end) diff --combined test/user_test.exs index 092cfc5dc,935c9c5b1..a0657c7b6 --- a/test/user_test.exs +++ b/test/user_test.exs @@@ -672,12 -672,13 +672,13 @@@ defmodule Pleroma.UserTest d "status" => "hey @#{addressed.nickname} @#{addressed_remote.nickname}" }) - assert [addressed] == User.get_recipients_from_activity(activity) + assert Enum.map([actor, addressed], & &1.ap_id) -- + Enum.map(User.get_recipients_from_activity(activity), & &1.ap_id) == [] {:ok, user} = User.follow(user, actor) {:ok, _user_two} = User.follow(user_two, actor) recipients = User.get_recipients_from_activity(activity) - assert length(recipients) == 2 + assert length(recipients) == 3 assert user in recipients assert addressed in recipients end @@@ -775,61 -776,14 +776,61 @@@ end describe "User.search" do - test "finds a user, ranking by similarity" do - _user = insert(:user, %{name: "lain"}) - _user_two = insert(:user, %{name: "ean"}) - _user_three = insert(:user, %{name: "ebn", nickname: "lain@mastodon.social"}) - user_four = insert(:user, %{nickname: "lain@pleroma.soykaf.com"}) + test "finds a user by full or partial nickname" do + user = insert(:user, %{nickname: "john"}) - assert user_four == - User.search("lain@ple") |> List.first() |> Map.put(:search_distance, nil) + Enum.each(["john", "jo", "j"], fn query -> + assert user == User.search(query) |> List.first() |> Map.put(:search_rank, nil) + end) + end + + test "finds a user by full or partial name" do + user = insert(:user, %{name: "John Doe"}) + + Enum.each(["John Doe", "JOHN", "doe", "j d", "j", "d"], fn query -> + assert user == User.search(query) |> List.first() |> Map.put(:search_rank, nil) + end) + end + + test "finds users, preferring nickname matches over name matches" do + u1 = insert(:user, %{name: "lain", nickname: "nick1"}) + u2 = insert(:user, %{nickname: "lain", name: "nick1"}) + + assert [u2.id, u1.id] == Enum.map(User.search("lain"), & &1.id) + end + + test "finds users, considering density of matched tokens" do + u1 = insert(:user, %{name: "Bar Bar plus Word Word"}) + u2 = insert(:user, %{name: "Word Word Bar Bar Bar"}) + + assert [u2.id, u1.id] == Enum.map(User.search("bar word"), & &1.id) + end + + test "finds users, ranking by similarity" do + u1 = insert(:user, %{name: "lain"}) + _u2 = insert(:user, %{name: "ean"}) + u3 = insert(:user, %{name: "ebn", nickname: "lain@mastodon.social"}) + u4 = insert(:user, %{nickname: "lain@pleroma.soykaf.com"}) + + assert [u4.id, u3.id, u1.id] == Enum.map(User.search("lain@ple"), & &1.id) + end + + test "finds users, handling misspelled requests" do + u1 = insert(:user, %{name: "lain"}) + + assert [u1.id] == Enum.map(User.search("laiin"), & &1.id) + end + + test "finds users, boosting ranks of friends and followers" do + u1 = insert(:user) + u2 = insert(:user, %{name: "Doe"}) + follower = insert(:user, %{name: "Doe"}) + friend = insert(:user, %{name: "Doe"}) + + {:ok, follower} = User.follow(follower, u1) + {:ok, u1} = User.follow(u1, friend) + + assert [friend.id, follower.id, u2.id] == Enum.map(User.search("doe", false, u1), & &1.id) end test "finds a user whose name is nil" do @@@ -839,15 -793,7 +840,15 @@@ assert user_two == User.search("lain@pleroma.soykaf.com") |> List.first() - |> Map.put(:search_distance, nil) + |> Map.put(:search_rank, nil) + end + + test "does not yield false-positive matches" do + insert(:user, %{name: "John Doe"}) + + Enum.each(["mary", "a", ""], fn query -> + assert [] == User.search(query) + end) end end @@@ -929,19 -875,4 +930,19 @@@ Pleroma.Config.put([:instance, :account_activation_required], false) end end + + describe "parse_bio/2" do + test "preserves hosts in user links text" do + remote_user = insert(:user, local: false, nickname: "nick@domain.com") + user = insert(:user) + bio = "A.k.a. @nick@domain.com" + + expected_text = + "A.k.a. " <> "@nick@domain.com" + + assert expected_text == User.parse_bio(bio, user) + end + end end diff --combined test/web/activity_pub/activity_pub_test.exs index 18f094379,6b1debc61..d2e54d804 --- a/test/web/activity_pub/activity_pub_test.exs +++ b/test/web/activity_pub/activity_pub_test.exs @@@ -160,7 -160,7 +160,7 @@@ defmodule Pleroma.Web.ActivityPub.Activ assert activity.data["to"] == ["user1", "user2"] assert activity.actor == user.ap_id - assert activity.recipients == ["user1", "user2"] + assert activity.recipients == ["user1", "user2", user.ap_id] end end @@@ -216,7 -216,7 +216,7 @@@ {:ok, user} = User.block(user, %{ap_id: activity_three.data["actor"]}) {:ok, _announce, %{data: %{"id" => id}}} = CommonAPI.repeat(activity_three.id, booster) - %Activity{} = boost_activity = Activity.get_create_activity_by_object_ap_id(id) + %Activity{} = boost_activity = Activity.get_create_by_object_ap_id(id) activity_three = Repo.get(Activity, activity_three.id) activities = ActivityPub.fetch_activities([], %{"blocking_user" => user}) @@@ -330,7 -330,7 +330,7 @@@ assert like_activity == same_like_activity assert object.data["likes"] == [user.ap_id] - [note_activity] = Activity.all_by_object_ap_id(object.data["id"]) + [note_activity] = Activity.get_all_create_by_object_ap_id(object.data["id"]) assert note_activity.data["object"]["like_count"] == 1 {:ok, _like_activity, object} = ActivityPub.like(user_two, object) @@@ -445,7 -445,7 +445,7 @@@ {:ok, object} = ActivityPub.fetch_object_from_id("http://mastodon.example.org/@admin/99541947525187367") - assert activity = Activity.get_create_activity_by_object_ap_id(object.data["id"]) + assert activity = Activity.get_create_by_object_ap_id(object.data["id"]) assert activity.data["id"] {:ok, object_again} = @@@ -459,7 -459,7 +459,7 @@@ test "it works with objects only available via Ostatus" do {:ok, object} = ActivityPub.fetch_object_from_id("https://shitposter.club/notice/2827873") - assert activity = Activity.get_create_activity_by_object_ap_id(object.data["id"]) + assert activity = Activity.get_create_by_object_ap_id(object.data["id"]) assert activity.data["id"] {:ok, object_again} = diff --combined test/web/mastodon_api/mastodon_api_controller_test.exs index 8443dc856,fdd3f1213..6004285d6 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@@ -10,7 -10,6 +10,7 @@@ defmodule Pleroma.Web.MastodonAPI.Masto alias Pleroma.Web.{OStatus, CommonAPI} alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.MastodonAPI.FilterView + alias Ecto.Changeset import Pleroma.Factory import ExUnit.CaptureLog import Tesla.Mock @@@ -148,7 -147,7 +148,7 @@@ assert %{"id" => id, "visibility" => "direct"} = json_response(conn, 200) assert activity = Repo.get(Activity, id) - assert activity.recipients == [user2.ap_id] + assert activity.recipients == [user2.ap_id, user1.ap_id] assert activity.data["to"] == [user2.ap_id] assert activity.data["cc"] == [] end @@@ -182,6 -181,16 +182,16 @@@ assert %{"visibility" => "direct"} = status assert status["url"] != direct.data["id"] + # User should be able to see his own direct message + res_conn = + build_conn() + |> assign(:user, user_one) + |> get("api/v1/timelines/direct") + + [status] = json_response(res_conn, 200) + + assert %{"visibility" => "direct"} = status + # Both should be visible here res_conn = conn @@@ -387,7 -396,7 +397,7 @@@ |> assign(:user, user) |> get("/api/v1/filters/#{filter.filter_id}") - assert response = json_response(conn, 200) + assert _response = json_response(conn, 200) end test "update a filter", %{conn: conn} do @@@ -601,9 -610,7 +611,9 @@@ |> get("/api/v1/notifications") expected_response = - "hi @#{user.nickname}" + "hi @#{user.nickname}" assert [%{"status" => %{"content" => response}} | _rest] = json_response(conn, 200) assert response == expected_response @@@ -624,9 -631,7 +634,9 @@@ |> get("/api/v1/notifications/#{notification.id}") expected_response = - "hi @#{user.nickname}" + "hi @#{user.nickname}" assert %{"status" => %{"content" => response}} = json_response(conn, 200) assert response == expected_response @@@ -1362,7 -1367,7 +1372,7 @@@ assert [status] = json_response(first_conn, 200) assert status["id"] == to_string(activity.id) - assert [{"link", link_header}] = + assert [{"link", _link_header}] = Enum.filter(first_conn.resp_headers, fn element -> match?({"link", _}, element) end) # Honours query params @@@ -1407,9 -1412,9 +1417,9 @@@ assert user = json_response(conn, 200) assert user["note"] == - "I drink #cofe with #cofe with @#{user2.nickname}" + }\" class=\"u-url mention\" href=\"#{user2.ap_id}\">@#{user2.nickname}" end test "updates the user's locking status", %{conn: conn} do @@@ -1474,51 -1479,22 +1484,51 @@@ end test "get instance information", %{conn: conn} do - insert(:user, %{local: true}) user = insert(:user, %{local: true}) - insert(:user, %{local: false}) + + user2 = insert(:user, %{local: true}) + {:ok, _user2} = User.deactivate(user2, !user2.info.deactivated) + + insert(:user, %{local: false, nickname: "u@peer1.com"}) + insert(:user, %{local: false, nickname: "u@peer2.com"}) {:ok, _} = TwitterAPI.create_status(user, %{"status" => "cofe"}) + # Stats should count users with missing or nil `info.deactivated` value + user = Repo.get(User, user.id) + info_change = Changeset.change(user.info, %{deactivated: nil}) + + {:ok, _user} = + user + |> Changeset.change() + |> Changeset.put_embed(:info, info_change) + |> User.update_and_set_cache() + Pleroma.Stats.update_stats() - conn = - conn - |> get("/api/v1/instance") + conn = get(conn, "/api/v1/instance") + + assert result = json_response(conn, 200) + + stats = result["stats"] + + assert stats + assert stats["user_count"] == 1 + assert stats["status_count"] == 1 + assert stats["domain_count"] == 2 + end + + test "get peers", %{conn: conn} do + insert(:user, %{local: false, nickname: "u@peer1.com"}) + insert(:user, %{local: false, nickname: "u@peer2.com"}) + + Pleroma.Stats.update_stats() + + conn = get(conn, "/api/v1/instance/peers") assert result = json_response(conn, 200) - assert result["stats"]["user_count"] == 2 - assert result["stats"]["status_count"] == 1 + assert ["peer1.com", "peer2.com"] == Enum.sort(result) end test "put settings", %{conn: conn} do @@@ -1529,7 -1505,7 +1539,7 @@@ |> assign(:user, user) |> put("/api/web/settings", %{"data" => %{"programming" => "socks"}}) - assert result = json_response(conn, 200) + assert _result = json_response(conn, 200) user = User.get_cached_by_ap_id(user.ap_id) assert user.info.settings == %{"programming" => "socks"} diff --combined test/web/mastodon_api/status_view_test.exs index e33479368,82bf71c70..ebf6273e8 --- a/test/web/mastodon_api/status_view_test.exs +++ b/test/web/mastodon_api/status_view_test.exs @@@ -19,36 -19,6 +19,36 @@@ defmodule Pleroma.Web.MastodonAPI.Statu :ok end + test "returns a temporary ap_id based user for activities missing db users" do + user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"}) + + Repo.delete(user) + Cachex.clear(:user_cache) + + %{account: ms_user} = StatusView.render("status.json", activity: activity) + + assert ms_user.acct == "erroruser@example.com" + end + + test "tries to get a user by nickname if fetching by ap_id doesn't work" do + user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"}) + + {:ok, user} = + user + |> Ecto.Changeset.change(%{ap_id: "#{user.ap_id}/extension/#{user.nickname}"}) + |> Repo.update() + + Cachex.clear(:user_cache) + + result = StatusView.render("status.json", activity: activity) + + assert result[:account][:id] == to_string(user.id) + end + test "a note with null content" do note = insert(:note_activity) @@@ -149,7 -119,10 +149,10 @@@ status = StatusView.render("status.json", %{activity: activity}) - assert status.mentions == [AccountView.render("mention.json", %{user: user})] + actor = Repo.get_by(User, ap_id: activity.actor) + + assert status.mentions == + Enum.map([user, actor], fn u -> AccountView.render("mention.json", %{user: u}) end) end test "attachments" do @@@ -202,7 -175,7 +205,7 @@@ "https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3" ) - %Activity{} = activity = Activity.get_create_activity_by_object_ap_id(object.data["id"]) + %Activity{} = activity = Activity.get_create_by_object_ap_id(object.data["id"]) represented = StatusView.render("status.json", %{for: user, activity: activity})