Remove most of Pleroma.Web.TwitterAPI.TwitterAPI

This commit is contained in:
rinpatch 2019-08-31 10:20:34 +03:00
parent eb1739c596
commit 90c2dae9a4
9 changed files with 42 additions and 1361 deletions

View file

@ -3,133 +3,14 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
alias Pleroma.Activity
alias Pleroma.Emails.Mailer
alias Pleroma.Emails.UserEmail
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.UserInviteToken
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.TwitterAPI.UserView
import Ecto.Query
require Pleroma.Constants
def create_status(%User{} = user, %{"status" => _} = data) do
CommonAPI.post(user, data)
end
def delete(%User{} = user, id) do
with %Activity{data: %{"type" => _type}} <- Activity.get_by_id(id),
{:ok, activity} <- CommonAPI.delete(id, user) do
{:ok, activity}
end
end
def follow(%User{} = follower, params) do
with {:ok, %User{} = followed} <- get_user(params) do
CommonAPI.follow(follower, followed)
end
end
def unfollow(%User{} = follower, params) do
with {:ok, %User{} = unfollowed} <- get_user(params),
{:ok, follower} <- CommonAPI.unfollow(follower, unfollowed) do
{:ok, follower, unfollowed}
end
end
def block(%User{} = blocker, params) do
with {:ok, %User{} = blocked} <- get_user(params),
{:ok, blocker} <- User.block(blocker, blocked),
{:ok, _activity} <- ActivityPub.block(blocker, blocked) do
{:ok, blocker, blocked}
else
err -> err
end
end
def unblock(%User{} = blocker, params) do
with {:ok, %User{} = blocked} <- get_user(params),
{:ok, blocker} <- User.unblock(blocker, blocked),
{:ok, _activity} <- ActivityPub.unblock(blocker, blocked) do
{:ok, blocker, blocked}
else
err -> err
end
end
def repeat(%User{} = user, ap_id_or_id) do
with {:ok, _announce, %{data: %{"id" => id}}} <- CommonAPI.repeat(ap_id_or_id, user),
%Activity{} = activity <- Activity.get_create_by_object_ap_id(id) do
{:ok, activity}
end
end
def unrepeat(%User{} = user, ap_id_or_id) do
with {:ok, _unannounce, %{data: %{"id" => id}}} <- CommonAPI.unrepeat(ap_id_or_id, user),
%Activity{} = activity <- Activity.get_create_by_object_ap_id(id) do
{:ok, activity}
end
end
def pin(%User{} = user, ap_id_or_id) do
CommonAPI.pin(ap_id_or_id, user)
end
def unpin(%User{} = user, ap_id_or_id) do
CommonAPI.unpin(ap_id_or_id, user)
end
def fav(%User{} = user, ap_id_or_id) do
with {:ok, _fav, %{data: %{"id" => id}}} <- CommonAPI.favorite(ap_id_or_id, user),
%Activity{} = activity <- Activity.get_create_by_object_ap_id(id) do
{:ok, activity}
end
end
def unfav(%User{} = user, ap_id_or_id) do
with {:ok, _unfav, _fav, %{data: %{"id" => id}}} <- CommonAPI.unfavorite(ap_id_or_id, user),
%Activity{} = activity <- Activity.get_create_by_object_ap_id(id) do
{:ok, activity}
end
end
def upload(%Plug.Upload{} = file, %User{} = user, format \\ "xml") do
{:ok, object} = ActivityPub.upload(file, actor: User.ap_id(user))
url = List.first(object.data["url"])
href = url["href"]
type = url["mediaType"]
case format do
"xml" ->
# Fake this as good as possible...
"""
<?xml version="1.0" encoding="UTF-8"?>
<rsp stat="ok" xmlns:atom="http://www.w3.org/2005/Atom">
<mediaid>#{object.id}</mediaid>
<media_id>#{object.id}</media_id>
<media_id_string>#{object.id}</media_id_string>
<media_url>#{href}</media_url>
<mediaurl>#{href}</mediaurl>
<atom:link rel="enclosure" href="#{href}" type="#{type}"></atom:link>
</rsp>
"""
"json" ->
%{
media_id: object.id,
media_id_string: "#{object.id}}",
media_url: href,
size: 0
}
|> Jason.encode!()
end
end
def register_user(params, opts \\ []) do
token = params["token"]
@ -236,80 +117,4 @@ def password_reset(nickname_or_email) do
{:error, "unknown user"}
end
end
def get_user(user \\ nil, params) do
case params do
%{"user_id" => user_id} ->
case User.get_cached_by_nickname_or_id(user_id) do
nil ->
{:error, "No user with such user_id"}
%User{info: %{deactivated: true}} ->
{:error, "User has been disabled"}
user ->
{:ok, user}
end
%{"screen_name" => nickname} ->
case User.get_cached_by_nickname(nickname) do
nil -> {:error, "No user with such screen_name"}
target -> {:ok, target}
end
_ ->
if user do
{:ok, user}
else
{:error, "You need to specify screen_name or user_id"}
end
end
end
defp parse_int(string, default)
defp parse_int(string, default) when is_binary(string) do
with {n, _} <- Integer.parse(string) do
n
else
_e -> default
end
end
defp parse_int(_, default), do: default
# TODO: unify the search query with MastoAPI one and do only pagination here
def search(_user, %{"q" => query} = params) do
limit = parse_int(params["rpp"], 20)
page = parse_int(params["page"], 1)
offset = (page - 1) * limit
q =
from(
[a, o] in Activity.with_preloaded_object(Activity),
where: fragment("?->>'type' = 'Create'", a.data),
where: ^Pleroma.Constants.as_public() in a.recipients,
where:
fragment(
"to_tsvector('english', ?->>'content') @@ plainto_tsquery('english', ?)",
o.data,
^query
),
limit: ^limit,
offset: ^offset,
# this one isn't indexed so psql won't take the wrong index.
order_by: [desc: :inserted_at]
)
_activities = Repo.all(q)
end
def get_external_profile(for_user, uri) do
with {:ok, %User{} = user} <- User.get_or_fetch(uri) do
{:ok, UserView.render("show.json", %{user: user, for: for_user})}
else
_e ->
{:error, "Couldn't find user"}
end
end
end

View file

@ -12,7 +12,6 @@ defmodule Pleroma.NotificationTest do
alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Streamer
alias Pleroma.Web.TwitterAPI.TwitterAPI
describe "create_notifications" do
test "notifies someone when they are directly addressed" do
@ -21,7 +20,7 @@ test "notifies someone when they are directly addressed" do
third_user = insert(:user)
{:ok, activity} =
TwitterAPI.create_status(user, %{
CommonAPI.post(user, %{
"status" => "hey @#{other_user.nickname} and @#{third_user.nickname}"
})
@ -39,7 +38,7 @@ test "it creates a notification for subscribed users" do
User.subscribe(subscriber, user)
{:ok, status} = TwitterAPI.create_status(user, %{"status" => "Akariiiin"})
{:ok, status} = CommonAPI.post(user, %{"status" => "Akariiiin"})
{:ok, [notification]} = Notification.create_notifications(status)
assert notification.user_id == subscriber.id
@ -184,47 +183,20 @@ test "it doesn't create a notification for user if he is the activity author" do
test "it doesn't create a notification for follow-unfollow-follow chains" do
user = insert(:user)
followed_user = insert(:user)
{:ok, _, _, activity} = TwitterAPI.follow(user, %{"user_id" => followed_user.id})
{:ok, _, _, activity} = CommonAPI.follow(user, followed_user)
Notification.create_notification(activity, followed_user)
TwitterAPI.unfollow(user, %{"user_id" => followed_user.id})
{:ok, _, _, activity_dupe} = TwitterAPI.follow(user, %{"user_id" => followed_user.id})
CommonAPI.unfollow(user, followed_user)
{:ok, _, _, activity_dupe} = CommonAPI.follow(user, followed_user)
refute Notification.create_notification(activity_dupe, followed_user)
end
test "it doesn't create a notification for like-unlike-like chains" do
user = insert(:user)
liked_user = insert(:user)
{:ok, status} = TwitterAPI.create_status(liked_user, %{"status" => "Yui is best yuru"})
{:ok, fav_status} = TwitterAPI.fav(user, status.id)
Notification.create_notification(fav_status, liked_user)
TwitterAPI.unfav(user, status.id)
{:ok, dupe} = TwitterAPI.fav(user, status.id)
refute Notification.create_notification(dupe, liked_user)
end
test "it doesn't create a notification for repeat-unrepeat-repeat chains" do
user = insert(:user)
retweeted_user = insert(:user)
{:ok, status} =
TwitterAPI.create_status(retweeted_user, %{
"status" => "Send dupe notifications to the shadow realm"
})
{:ok, retweeted_activity} = TwitterAPI.repeat(user, status.id)
Notification.create_notification(retweeted_activity, retweeted_user)
TwitterAPI.unrepeat(user, status.id)
{:ok, dupe} = TwitterAPI.repeat(user, status.id)
refute Notification.create_notification(dupe, retweeted_user)
end
test "it doesn't create duplicate notifications for follow+subscribed users" do
user = insert(:user)
subscriber = insert(:user)
{:ok, _, _, _} = TwitterAPI.follow(subscriber, %{"user_id" => user.id})
{:ok, _, _, _} = CommonAPI.follow(subscriber, user)
User.subscribe(subscriber, user)
{:ok, status} = TwitterAPI.create_status(user, %{"status" => "Akariiiin"})
{:ok, status} = CommonAPI.post(user, %{"status" => "Akariiiin"})
{:ok, [_notif]} = Notification.create_notifications(status)
end
@ -234,8 +206,7 @@ test "it doesn't create subscription notifications if the recipient cannot see t
User.subscribe(subscriber, user)
{:ok, status} =
TwitterAPI.create_status(user, %{"status" => "inwisible", "visibility" => "direct"})
{:ok, status} = CommonAPI.post(user, %{"status" => "inwisible", "visibility" => "direct"})
assert {:ok, []} == Notification.create_notifications(status)
end
@ -246,8 +217,7 @@ test "it gets a notification that belongs to the user" do
user = insert(:user)
other_user = insert(:user)
{:ok, activity} =
TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"})
{:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}"})
{:ok, [notification]} = Notification.create_notifications(activity)
{:ok, notification} = Notification.get(other_user, notification.id)
@ -259,8 +229,7 @@ test "it returns error if the notification doesn't belong to the user" do
user = insert(:user)
other_user = insert(:user)
{:ok, activity} =
TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"})
{:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}"})
{:ok, [notification]} = Notification.create_notifications(activity)
{:error, _notification} = Notification.get(user, notification.id)
@ -272,8 +241,7 @@ test "it dismisses a notification that belongs to the user" do
user = insert(:user)
other_user = insert(:user)
{:ok, activity} =
TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"})
{:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}"})
{:ok, [notification]} = Notification.create_notifications(activity)
{:ok, notification} = Notification.dismiss(other_user, notification.id)
@ -285,8 +253,7 @@ test "it returns error if the notification doesn't belong to the user" do
user = insert(:user)
other_user = insert(:user)
{:ok, activity} =
TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"})
{:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}"})
{:ok, [notification]} = Notification.create_notifications(activity)
{:error, _notification} = Notification.dismiss(user, notification.id)
@ -300,14 +267,14 @@ test "it clears all notifications belonging to the user" do
third_user = insert(:user)
{:ok, activity} =
TwitterAPI.create_status(user, %{
CommonAPI.post(user, %{
"status" => "hey @#{other_user.nickname} and @#{third_user.nickname} !"
})
{:ok, _notifs} = Notification.create_notifications(activity)
{:ok, activity} =
TwitterAPI.create_status(user, %{
CommonAPI.post(user, %{
"status" => "hey again @#{other_user.nickname} and @#{third_user.nickname} !"
})
@ -325,12 +292,12 @@ test "it sets all notifications as read up to a specified notification ID" do
other_user = insert(:user)
{:ok, _activity} =
TwitterAPI.create_status(user, %{
CommonAPI.post(user, %{
"status" => "hey @#{other_user.nickname}!"
})
{:ok, _activity} =
TwitterAPI.create_status(user, %{
CommonAPI.post(user, %{
"status" => "hey again @#{other_user.nickname}!"
})
@ -340,7 +307,7 @@ test "it sets all notifications as read up to a specified notification ID" do
assert n2.id > n1.id
{:ok, _activity} =
TwitterAPI.create_status(user, %{
CommonAPI.post(user, %{
"status" => "hey yet again @#{other_user.nickname}!"
})
@ -677,7 +644,7 @@ test "it returns notifications for muted user without notifications" do
muted = insert(:user)
{:ok, user} = User.mute(user, muted, false)
{:ok, _activity} = TwitterAPI.create_status(muted, %{"status" => "hey @#{user.nickname}"})
{:ok, _activity} = CommonAPI.post(muted, %{"status" => "hey @#{user.nickname}"})
assert length(Notification.for_user(user)) == 1
end
@ -687,7 +654,7 @@ test "it doesn't return notifications for muted user with notifications" do
muted = insert(:user)
{:ok, user} = User.mute(user, muted)
{:ok, _activity} = TwitterAPI.create_status(muted, %{"status" => "hey @#{user.nickname}"})
{:ok, _activity} = CommonAPI.post(muted, %{"status" => "hey @#{user.nickname}"})
assert Notification.for_user(user) == []
end
@ -697,7 +664,7 @@ test "it doesn't return notifications for blocked user" do
blocked = insert(:user)
{:ok, user} = User.block(user, blocked)
{:ok, _activity} = TwitterAPI.create_status(blocked, %{"status" => "hey @#{user.nickname}"})
{:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"})
assert Notification.for_user(user) == []
end
@ -707,7 +674,7 @@ test "it doesn't return notificatitons for blocked domain" do
blocked = insert(:user, ap_id: "http://some-domain.com")
{:ok, user} = User.block_domain(user, "some-domain.com")
{:ok, _activity} = TwitterAPI.create_status(blocked, %{"status" => "hey @#{user.nickname}"})
{:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"})
assert Notification.for_user(user) == []
end
@ -716,8 +683,7 @@ test "it doesn't return notifications for muted thread" do
user = insert(:user)
another_user = insert(:user)
{:ok, activity} =
TwitterAPI.create_status(another_user, %{"status" => "hey @#{user.nickname}"})
{:ok, activity} = CommonAPI.post(another_user, %{"status" => "hey @#{user.nickname}"})
{:ok, _} = Pleroma.ThreadMute.add_mute(user.id, activity.data["context"])
assert Notification.for_user(user) == []
@ -728,7 +694,7 @@ test "it returns notifications for muted user with notifications and with_muted
muted = insert(:user)
{:ok, user} = User.mute(user, muted)
{:ok, _activity} = TwitterAPI.create_status(muted, %{"status" => "hey @#{user.nickname}"})
{:ok, _activity} = CommonAPI.post(muted, %{"status" => "hey @#{user.nickname}"})
assert length(Notification.for_user(user, %{with_muted: true})) == 1
end
@ -738,7 +704,7 @@ test "it returns notifications for blocked user and with_muted parameter" do
blocked = insert(:user)
{:ok, user} = User.block(user, blocked)
{:ok, _activity} = TwitterAPI.create_status(blocked, %{"status" => "hey @#{user.nickname}"})
{:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"})
assert length(Notification.for_user(user, %{with_muted: true})) == 1
end
@ -748,7 +714,7 @@ test "it returns notificatitons for blocked domain and with_muted parameter" do
blocked = insert(:user, ap_id: "http://some-domain.com")
{:ok, user} = User.block_domain(user, "some-domain.com")
{:ok, _activity} = TwitterAPI.create_status(blocked, %{"status" => "hey @#{user.nickname}"})
{:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"})
assert length(Notification.for_user(user, %{with_muted: true})) == 1
end
@ -757,8 +723,7 @@ test "it returns notifications for muted thread with_muted parameter" do
user = insert(:user)
another_user = insert(:user)
{:ok, activity} =
TwitterAPI.create_status(another_user, %{"status" => "hey @#{user.nickname}"})
{:ok, activity} = CommonAPI.post(another_user, %{"status" => "hey @#{user.nickname}"})
{:ok, _} = Pleroma.ThreadMute.add_mute(user.id, activity.data["context"])
assert length(Notification.for_user(user, %{with_muted: true})) == 1

View file

@ -69,8 +69,8 @@ test "returns all pending follow requests" do
locked = insert(:user, %{info: %{locked: true}})
follower = insert(:user)
Pleroma.Web.TwitterAPI.TwitterAPI.follow(follower, %{"user_id" => unlocked.id})
Pleroma.Web.TwitterAPI.TwitterAPI.follow(follower, %{"user_id" => locked.id})
CommonAPI.follow(follower, unlocked)
CommonAPI.follow(follower, locked)
assert {:ok, []} = User.get_follow_requests(unlocked)
assert {:ok, [activity]} = User.get_follow_requests(locked)
@ -83,9 +83,9 @@ test "doesn't return already accepted or duplicate follow requests" do
pending_follower = insert(:user)
accepted_follower = insert(:user)
Pleroma.Web.TwitterAPI.TwitterAPI.follow(pending_follower, %{"user_id" => locked.id})
Pleroma.Web.TwitterAPI.TwitterAPI.follow(pending_follower, %{"user_id" => locked.id})
Pleroma.Web.TwitterAPI.TwitterAPI.follow(accepted_follower, %{"user_id" => locked.id})
CommonAPI.follow(pending_follower, locked)
CommonAPI.follow(pending_follower, locked)
CommonAPI.follow(accepted_follower, locked)
User.follow(accepted_follower, locked)
assert {:ok, [activity]} = User.get_follow_requests(locked)
@ -1279,11 +1279,9 @@ test "follower count is updated when a follower is blocked" do
{:ok, _follower2} = User.follow(follower2, user)
{:ok, _follower3} = User.follow(follower3, user)
{:ok, _} = User.block(user, follower)
{:ok, user} = User.block(user, follower)
user_show = Pleroma.Web.TwitterAPI.UserView.render("show.json", %{user: user})
assert Map.get(user_show, "followers_count") == 2
assert User.user_info(user).follower_count == 2
end
describe "list_inactive_users_query/1" do
@ -1327,7 +1325,7 @@ test "Only includes users who has no recent activity" do
to = Enum.random(users -- [user])
{:ok, _} =
Pleroma.Web.TwitterAPI.TwitterAPI.create_status(user, %{
CommonAPI.post(user, %{
"status" => "hey @#{to.nickname}"
})
end)
@ -1359,12 +1357,12 @@ test "Only includes users with no read notifications" do
Enum.each(recipients, fn to ->
{:ok, _} =
Pleroma.Web.TwitterAPI.TwitterAPI.create_status(sender, %{
CommonAPI.post(sender, %{
"status" => "hey @#{to.nickname}"
})
{:ok, _} =
Pleroma.Web.TwitterAPI.TwitterAPI.create_status(sender, %{
CommonAPI.post(sender, %{
"status" => "hey again @#{to.nickname}"
})
end)

View file

@ -21,7 +21,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
alias Pleroma.Web.OAuth.Token
alias Pleroma.Web.OStatus
alias Pleroma.Web.Push
alias Pleroma.Web.TwitterAPI.TwitterAPI
import Pleroma.Factory
import ExUnit.CaptureLog
import Tesla.Mock
@ -1583,12 +1582,9 @@ test "gets an users media", %{conn: conn} do
filename: "an_image.jpg"
}
media =
TwitterAPI.upload(file, user, "json")
|> Jason.decode!()
{:ok, %{id: media_id}} = ActivityPub.upload(file, actor: user.ap_id)
{:ok, image_post} =
CommonAPI.post(user, %{"status" => "cofe", "media_ids" => [media["media_id"]]})
{:ok, image_post} = CommonAPI.post(user, %{"status" => "cofe", "media_ids" => [media_id]})
conn =
conn

View file

@ -8,8 +8,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPITest do
alias Pleroma.Notification
alias Pleroma.ScheduledActivity
alias Pleroma.User
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.MastodonAPI.MastodonAPI
alias Pleroma.Web.TwitterAPI.TwitterAPI
import Pleroma.Factory
@ -75,8 +75,9 @@ test "returns notifications for user" do
User.subscribe(subscriber, user)
{:ok, status} = TwitterAPI.create_status(user, %{"status" => "Akariiiin"})
{:ok, status1} = TwitterAPI.create_status(user, %{"status" => "Magi"})
{:ok, status} = CommonAPI.post(user, %{"status" => "Akariiiin"})
{:ok, status1} = CommonAPI.post(user, %{"status" => "Magi"})
{:ok, [notification]} = Notification.create_notifications(status)
{:ok, [notification1]} = Notification.create_notifications(status1)
res = MastodonAPI.get_notifications(subscriber)

View file

@ -4,12 +4,9 @@
defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
use Pleroma.DataCase
alias Pleroma.Activity
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.UserInviteToken
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.TwitterAPI.ActivityView
alias Pleroma.Web.TwitterAPI.TwitterAPI
alias Pleroma.Web.TwitterAPI.UserView
@ -21,253 +18,6 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
:ok
end
test "create a status" do
user = insert(:user)
mentioned_user = insert(:user, %{nickname: "shp", ap_id: "shp"})
object_data = %{
"type" => "Image",
"url" => [
%{
"type" => "Link",
"mediaType" => "image/jpg",
"href" => "http://example.org/image.jpg"
}
],
"uuid" => 1
}
object = Repo.insert!(%Object{data: object_data})
input = %{
"status" =>
"Hello again, @shp.<script></script>\nThis is on another :firefox: line. #2hu #epic #phantasmagoric",
"media_ids" => [object.id]
}
{:ok, activity = %Activity{}} = TwitterAPI.create_status(user, input)
object = Object.normalize(activity)
expected_text =
"Hello again, <span class='h-card'><a data-user='#{mentioned_user.id}' class='u-url mention' href='shp'>@<span>shp</span></a></span>.&lt;script&gt;&lt;/script&gt;<br>This is on another :firefox: line. <a class='hashtag' data-tag='2hu' href='http://localhost:4001/tag/2hu' rel='tag'>#2hu</a> <a class='hashtag' data-tag='epic' href='http://localhost:4001/tag/epic' rel='tag'>#epic</a> <a class='hashtag' data-tag='phantasmagoric' href='http://localhost:4001/tag/phantasmagoric' rel='tag'>#phantasmagoric</a><br><a href=\"http://example.org/image.jpg\" class='attachment'>image.jpg</a>"
assert get_in(object.data, ["content"]) == expected_text
assert get_in(object.data, ["type"]) == "Note"
assert get_in(object.data, ["actor"]) == user.ap_id
assert get_in(activity.data, ["actor"]) == user.ap_id
assert Enum.member?(get_in(activity.data, ["cc"]), User.ap_followers(user))
assert Enum.member?(
get_in(activity.data, ["to"]),
"https://www.w3.org/ns/activitystreams#Public"
)
assert Enum.member?(get_in(activity.data, ["to"]), "shp")
assert activity.local == true
assert %{"firefox" => "http://localhost:4001/emoji/Firefox.gif"} = object.data["emoji"]
# hashtags
assert object.data["tag"] == ["2hu", "epic", "phantasmagoric"]
# Add a context
assert is_binary(get_in(activity.data, ["context"]))
assert is_binary(get_in(object.data, ["context"]))
assert is_list(object.data["attachment"])
assert activity.data["object"] == object.data["id"]
user = User.get_cached_by_ap_id(user.ap_id)
assert user.info.note_count == 1
end
test "create a status that is a reply" do
user = insert(:user)
input = %{
"status" => "Hello again."
}
{:ok, activity = %Activity{}} = TwitterAPI.create_status(user, input)
object = Object.normalize(activity)
input = %{
"status" => "Here's your (you).",
"in_reply_to_status_id" => activity.id
}
{:ok, reply = %Activity{}} = TwitterAPI.create_status(user, input)
reply_object = Object.normalize(reply)
assert get_in(reply.data, ["context"]) == get_in(activity.data, ["context"])
assert get_in(reply_object.data, ["context"]) == get_in(object.data, ["context"])
assert get_in(reply_object.data, ["inReplyTo"]) == get_in(activity.data, ["object"])
assert Activity.get_in_reply_to_activity(reply).id == activity.id
end
test "Follow another user using user_id" do
user = insert(:user)
followed = insert(:user)
{:ok, user, followed, _activity} = TwitterAPI.follow(user, %{"user_id" => followed.id})
assert User.ap_followers(followed) in user.following
{:ok, _, _, _} = TwitterAPI.follow(user, %{"user_id" => followed.id})
end
test "Follow another user using screen_name" do
user = insert(:user)
followed = insert(:user)
{:ok, user, followed, _activity} =
TwitterAPI.follow(user, %{"screen_name" => followed.nickname})
assert User.ap_followers(followed) in user.following
followed = User.get_cached_by_ap_id(followed.ap_id)
assert followed.info.follower_count == 1
{:ok, _, _, _} = TwitterAPI.follow(user, %{"screen_name" => followed.nickname})
end
test "Unfollow another user using user_id" do
unfollowed = insert(:user)
user = insert(:user, %{following: [User.ap_followers(unfollowed)]})
ActivityPub.follow(user, unfollowed)
{:ok, user, unfollowed} = TwitterAPI.unfollow(user, %{"user_id" => unfollowed.id})
assert user.following == []
{:error, msg} = TwitterAPI.unfollow(user, %{"user_id" => unfollowed.id})
assert msg == "Not subscribed!"
end
test "Unfollow another user using screen_name" do
unfollowed = insert(:user)
user = insert(:user, %{following: [User.ap_followers(unfollowed)]})
ActivityPub.follow(user, unfollowed)
{:ok, user, unfollowed} = TwitterAPI.unfollow(user, %{"screen_name" => unfollowed.nickname})
assert user.following == []
{:error, msg} = TwitterAPI.unfollow(user, %{"screen_name" => unfollowed.nickname})
assert msg == "Not subscribed!"
end
test "Block another user using user_id" do
user = insert(:user)
blocked = insert(:user)
{:ok, user, blocked} = TwitterAPI.block(user, %{"user_id" => blocked.id})
assert User.blocks?(user, blocked)
end
test "Block another user using screen_name" do
user = insert(:user)
blocked = insert(:user)
{:ok, user, blocked} = TwitterAPI.block(user, %{"screen_name" => blocked.nickname})
assert User.blocks?(user, blocked)
end
test "Unblock another user using user_id" do
unblocked = insert(:user)
user = insert(:user)
{:ok, user, _unblocked} = TwitterAPI.block(user, %{"user_id" => unblocked.id})
{:ok, user, _unblocked} = TwitterAPI.unblock(user, %{"user_id" => unblocked.id})
assert user.info.blocks == []
end
test "Unblock another user using screen_name" do
unblocked = insert(:user)
user = insert(:user)
{:ok, user, _unblocked} = TwitterAPI.block(user, %{"screen_name" => unblocked.nickname})
{:ok, user, _unblocked} = TwitterAPI.unblock(user, %{"screen_name" => unblocked.nickname})
assert user.info.blocks == []
end
test "upload a file" do
user = insert(:user)
file = %Plug.Upload{
content_type: "image/jpg",
path: Path.absname("test/fixtures/image.jpg"),
filename: "an_image.jpg"
}
response = TwitterAPI.upload(file, user)
assert is_binary(response)
end
test "it favorites a status, returns the updated activity" do
user = insert(:user)
other_user = insert(:user)
note_activity = insert(:note_activity)
{:ok, status} = TwitterAPI.fav(user, note_activity.id)
updated_activity = Activity.get_by_ap_id(note_activity.data["id"])
assert ActivityView.render("activity.json", %{activity: updated_activity})["fave_num"] == 1
object = Object.normalize(note_activity)
assert object.data["like_count"] == 1
assert status == updated_activity
{:ok, _status} = TwitterAPI.fav(other_user, note_activity.id)
object = Object.normalize(note_activity)
assert object.data["like_count"] == 2
updated_activity = Activity.get_by_ap_id(note_activity.data["id"])
assert ActivityView.render("activity.json", %{activity: updated_activity})["fave_num"] == 2
end
test "it unfavorites a status, returns the updated activity" do
user = insert(:user)
note_activity = insert(:note_activity)
object = Object.normalize(note_activity)
{:ok, _like_activity, _object} = ActivityPub.like(user, object)
updated_activity = Activity.get_by_ap_id(note_activity.data["id"])
assert ActivityView.render("activity.json", activity: updated_activity)["fave_num"] == 1
{:ok, activity} = TwitterAPI.unfav(user, note_activity.id)
assert ActivityView.render("activity.json", activity: activity)["fave_num"] == 0
end
test "it retweets a status and returns the retweet" do
user = insert(:user)
note_activity = insert(:note_activity)
{:ok, status} = TwitterAPI.repeat(user, note_activity.id)
updated_activity = Activity.get_by_ap_id(note_activity.data["id"])
assert status == updated_activity
end
test "it unretweets an already retweeted status" do
user = insert(:user)
note_activity = insert(:note_activity)
{:ok, _status} = TwitterAPI.repeat(user, note_activity.id)
{:ok, status} = TwitterAPI.unrepeat(user, note_activity.id)
updated_activity = Activity.get_by_ap_id(note_activity.data["id"])
assert status == updated_activity
end
test "it registers a new user and returns the user." do
data = %{
"nickname" => "lain",
@ -701,19 +451,4 @@ test "it assigns an integer conversation_id" do
Supervisor.restart_child(Pleroma.Supervisor, Cachex)
:ok
end
describe "fetching a user by uri" do
test "fetches a user by uri" do
id = "https://mastodon.social/users/lambadalambda"
user = insert(:user)
{:ok, represented} = TwitterAPI.get_external_profile(user, id)
remote = User.get_cached_by_ap_id(id)
assert represented["id"] == UserView.render("show.json", %{user: remote, for: user})["id"]
# Also fetches the feed.
# assert Activity.get_create_by_object_ap_id("tag:mastodon.social,2017-04-05:objectId=1641750:objectType=Status")
# credo:disable-for-previous-line Credo.Check.Readability.MaxLineLength
end
end
end

View file

@ -1,384 +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.TwitterAPI.ActivityViewTest do
use Pleroma.DataCase
alias Pleroma.Activity
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Web.TwitterAPI.ActivityView
alias Pleroma.Web.TwitterAPI.UserView
import Pleroma.Factory
import Tesla.Mock
setup do
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
:ok
end
import Mock
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)
%{"user" => tw_user} = ActivityView.render("activity.json", activity: activity)
assert tw_user["screen_name"] == "erroruser@example.com"
assert tw_user["name"] == user.ap_id
assert tw_user["statusnet_profile_url"] == user.ap_id
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 = ActivityView.render("activity.json", activity: activity)
assert result["user"]["id"] == user.id
end
test "tells if the message is muted for some reason" do
user = insert(:user)
other_user = insert(:user)
{:ok, user} = User.mute(user, other_user)
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "test"})
status = ActivityView.render("activity.json", %{activity: activity})
assert status["muted"] == false
status = ActivityView.render("activity.json", %{activity: activity, for: user})
assert status["muted"] == true
end
test "a create activity with a html status" do
text = """
#Bike log - Commute Tuesday\nhttps://pla.bike/posts/20181211/\n#cycling #CHScycling #commute\nMVIMG_20181211_054020.jpg
"""
{:ok, activity} = CommonAPI.post(insert(:user), %{"status" => text})
result = ActivityView.render("activity.json", activity: activity)
assert result["statusnet_html"] ==
"<a class=\"hashtag\" data-tag=\"bike\" href=\"http://localhost:4001/tag/bike\" rel=\"tag\">#Bike</a> log - Commute Tuesday<br /><a href=\"https://pla.bike/posts/20181211/\">https://pla.bike/posts/20181211/</a><br /><a class=\"hashtag\" data-tag=\"cycling\" href=\"http://localhost:4001/tag/cycling\" rel=\"tag\">#cycling</a> <a class=\"hashtag\" data-tag=\"chscycling\" href=\"http://localhost:4001/tag/chscycling\" rel=\"tag\">#CHScycling</a> <a class=\"hashtag\" data-tag=\"commute\" href=\"http://localhost:4001/tag/commute\" rel=\"tag\">#commute</a><br />MVIMG_20181211_054020.jpg"
assert result["text"] ==
"#Bike log - Commute Tuesday\nhttps://pla.bike/posts/20181211/\n#cycling #CHScycling #commute\nMVIMG_20181211_054020.jpg"
end
test "a create activity with a summary containing emoji" do
{:ok, activity} =
CommonAPI.post(insert(:user), %{
"spoiler_text" => ":firefox: meow",
"status" => "."
})
result = ActivityView.render("activity.json", activity: activity)
expected = ":firefox: meow"
expected_html =
"<img class=\"emoji\" alt=\"firefox\" title=\"firefox\" src=\"http://localhost:4001/emoji/Firefox.gif\" /> meow"
assert result["summary"] == expected
assert result["summary_html"] == expected_html
end
test "a create activity with a summary containing invalid HTML" do
{:ok, activity} =
CommonAPI.post(insert(:user), %{
"spoiler_text" => "<span style=\"color: magenta; font-size: 32px;\">meow</span>",
"status" => "."
})
result = ActivityView.render("activity.json", activity: activity)
expected = "meow"
assert result["summary"] == expected
assert result["summary_html"] == expected
end
test "a create activity with a note" do
user = insert(:user)
other_user = insert(:user, %{nickname: "shp"})
{:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"})
object = Object.normalize(activity)
result = ActivityView.render("activity.json", activity: activity)
convo_id = Utils.context_to_conversation_id(object.data["context"])
expected = %{
"activity_type" => "post",
"attachments" => [],
"attentions" => [
UserView.render("show.json", %{user: other_user})
],
"created_at" => object.data["published"] |> Utils.date_to_asctime(),
"external_url" => object.data["id"],
"fave_num" => 0,
"favorited" => false,
"id" => activity.id,
"in_reply_to_status_id" => nil,
"in_reply_to_screen_name" => nil,
"in_reply_to_user_id" => nil,
"in_reply_to_profileurl" => nil,
"in_reply_to_ostatus_uri" => nil,
"is_local" => true,
"is_post_verb" => true,
"possibly_sensitive" => false,
"repeat_num" => 0,
"repeated" => false,
"pinned" => false,
"statusnet_conversation_id" => convo_id,
"summary" => "",
"summary_html" => "",
"statusnet_html" =>
"Hey <span class=\"h-card\"><a data-user=\"#{other_user.id}\" class=\"u-url mention\" href=\"#{
other_user.ap_id
}\">@<span>shp</span></a></span>!",
"tags" => [],
"text" => "Hey @shp!",
"uri" => object.data["id"],
"user" => UserView.render("show.json", %{user: user}),
"visibility" => "direct",
"card" => nil,
"muted" => false
}
assert result == expected
end
test "a list of activities" do
user = insert(:user)
other_user = insert(:user, %{nickname: "shp"})
{:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!"})
object = Object.normalize(activity)
convo_id = Utils.context_to_conversation_id(object.data["context"])
mocks = [
{
Utils,
[:passthrough],
[context_to_conversation_id: fn _ -> false end]
},
{
User,
[:passthrough],
[get_cached_by_ap_id: fn _ -> nil end]
}
]
with_mocks mocks do
[result] = ActivityView.render("index.json", activities: [activity])
assert result["statusnet_conversation_id"] == convo_id
assert result["user"]
refute called(Utils.context_to_conversation_id(:_))
refute called(User.get_cached_by_ap_id(user.ap_id))
refute called(User.get_cached_by_ap_id(other_user.ap_id))
end
end
test "an activity that is a reply" do
user = insert(:user)
other_user = insert(:user, %{nickname: "shp"})
{:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!"})
{:ok, answer} =
CommonAPI.post(other_user, %{"status" => "Hi!", "in_reply_to_status_id" => activity.id})
result = ActivityView.render("activity.json", %{activity: answer})
assert result["in_reply_to_status_id"] == activity.id
end
test "a like activity" do
user = insert(:user)
other_user = insert(:user, %{nickname: "shp"})
{:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!"})
{:ok, like, _object} = CommonAPI.favorite(activity.id, other_user)
result = ActivityView.render("activity.json", activity: like)
activity = Pleroma.Activity.get_by_ap_id(activity.data["id"])
expected = %{
"activity_type" => "like",
"created_at" => like.data["published"] |> Utils.date_to_asctime(),
"external_url" => like.data["id"],
"id" => like.id,
"in_reply_to_status_id" => activity.id,
"is_local" => true,
"is_post_verb" => false,
"favorited_status" => ActivityView.render("activity.json", activity: activity),
"statusnet_html" => "shp favorited a status.",
"text" => "shp favorited a status.",
"uri" => "tag:#{like.data["id"]}:objectType=Favourite",
"user" => UserView.render("show.json", user: other_user)
}
assert result == expected
end
test "a like activity for deleted post" do
user = insert(:user)
other_user = insert(:user, %{nickname: "shp"})
{:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!"})
{:ok, like, _object} = CommonAPI.favorite(activity.id, other_user)
CommonAPI.delete(activity.id, user)
result = ActivityView.render("activity.json", activity: like)
expected = %{
"activity_type" => "like",
"created_at" => like.data["published"] |> Utils.date_to_asctime(),
"external_url" => like.data["id"],
"id" => like.id,
"in_reply_to_status_id" => nil,
"is_local" => true,
"is_post_verb" => false,
"favorited_status" => nil,
"statusnet_html" => "shp favorited a status.",
"text" => "shp favorited a status.",
"uri" => "tag:#{like.data["id"]}:objectType=Favourite",
"user" => UserView.render("show.json", user: other_user)
}
assert result == expected
end
test "an announce activity" do
user = insert(:user)
other_user = insert(:user, %{nickname: "shp"})
{:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!"})
{:ok, announce, object} = CommonAPI.repeat(activity.id, other_user)
convo_id = Utils.context_to_conversation_id(object.data["context"])
activity = Activity.get_by_id(activity.id)
result = ActivityView.render("activity.json", activity: announce)
expected = %{
"activity_type" => "repeat",
"created_at" => announce.data["published"] |> Utils.date_to_asctime(),
"external_url" => announce.data["id"],
"id" => announce.id,
"is_local" => true,
"is_post_verb" => false,
"statusnet_html" => "shp repeated a status.",
"text" => "shp repeated a status.",
"uri" => "tag:#{announce.data["id"]}:objectType=note",
"user" => UserView.render("show.json", user: other_user),
"retweeted_status" => ActivityView.render("activity.json", activity: activity),
"statusnet_conversation_id" => convo_id
}
assert result == expected
end
test "A follow activity" do
user = insert(:user)
other_user = insert(:user, %{nickname: "shp"})
{:ok, follower} = User.follow(user, other_user)
{:ok, follow} = ActivityPub.follow(follower, other_user)
result = ActivityView.render("activity.json", activity: follow)
expected = %{
"activity_type" => "follow",
"attentions" => [],
"created_at" => follow.data["published"] |> Utils.date_to_asctime(),
"external_url" => follow.data["id"],
"id" => follow.id,
"in_reply_to_status_id" => nil,
"is_local" => true,
"is_post_verb" => false,
"statusnet_html" => "#{user.nickname} started following shp",
"text" => "#{user.nickname} started following shp",
"user" => UserView.render("show.json", user: user)
}
assert result == expected
end
test "a delete activity" do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!"})
{:ok, delete} = CommonAPI.delete(activity.id, user)
result = ActivityView.render("activity.json", activity: delete)
expected = %{
"activity_type" => "delete",
"attentions" => [],
"created_at" => delete.data["published"] |> Utils.date_to_asctime(),
"external_url" => delete.data["id"],
"id" => delete.id,
"in_reply_to_status_id" => nil,
"is_local" => true,
"is_post_verb" => false,
"statusnet_html" => "deleted notice {{tag",
"text" => "deleted notice {{tag",
"uri" => Object.normalize(delete).data["id"],
"user" => UserView.render("show.json", user: user)
}
assert result == expected
end
test "a peertube video" do
{:ok, object} =
Pleroma.Object.Fetcher.fetch_object_from_id(
"https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3"
)
%Activity{} = activity = Activity.get_create_by_object_ap_id(object.data["id"])
result = ActivityView.render("activity.json", activity: activity)
assert length(result["attachments"]) == 1
assert result["summary"] == "Friday Night"
end
test "special characters are not escaped in text field for status created" do
text = "<3 is on the way"
{:ok, activity} = CommonAPI.post(insert(:user), %{"status" => text})
result = ActivityView.render("activity.json", activity: activity)
assert result["text"] == text
end
end

View file

@ -1,112 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.NotificationViewTest do
use Pleroma.DataCase
alias Pleroma.Notification
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Web.TwitterAPI.ActivityView
alias Pleroma.Web.TwitterAPI.NotificationView
alias Pleroma.Web.TwitterAPI.TwitterAPI
alias Pleroma.Web.TwitterAPI.UserView
import Pleroma.Factory
setup do
user = insert(:user, bio: "<span>Here's some html</span>")
[user: user]
end
test "A follow notification" do
note_activity = insert(:note_activity)
user = User.get_cached_by_ap_id(note_activity.data["actor"])
follower = insert(:user)
{:ok, follower} = User.follow(follower, user)
{:ok, activity} = ActivityPub.follow(follower, user)
Cachex.put(:user_cache, "user_info:#{user.id}", User.user_info(Repo.get!(User, user.id)))
[follow_notif] = Notification.for_user(user)
represented = %{
"created_at" => follow_notif.inserted_at |> Utils.format_naive_asctime(),
"from_profile" => UserView.render("show.json", %{user: follower, for: user}),
"id" => follow_notif.id,
"is_seen" => 0,
"notice" => ActivityView.render("activity.json", %{activity: activity, for: user}),
"ntype" => "follow"
}
assert represented ==
NotificationView.render("notification.json", %{notification: follow_notif, for: user})
end
test "A mention notification" do
user = insert(:user)
other_user = insert(:user)
{:ok, activity} =
TwitterAPI.create_status(other_user, %{"status" => "Päivää, @#{user.nickname}"})
[notification] = Notification.for_user(user)
represented = %{
"created_at" => notification.inserted_at |> Utils.format_naive_asctime(),
"from_profile" => UserView.render("show.json", %{user: other_user, for: user}),
"id" => notification.id,
"is_seen" => 0,
"notice" => ActivityView.render("activity.json", %{activity: activity, for: user}),
"ntype" => "mention"
}
assert represented ==
NotificationView.render("notification.json", %{notification: notification, for: user})
end
test "A retweet notification" do
note_activity = insert(:note_activity)
user = User.get_cached_by_ap_id(note_activity.data["actor"])
repeater = insert(:user)
{:ok, _activity} = TwitterAPI.repeat(repeater, note_activity.id)
[notification] = Notification.for_user(user)
represented = %{
"created_at" => notification.inserted_at |> Utils.format_naive_asctime(),
"from_profile" => UserView.render("show.json", %{user: repeater, for: user}),
"id" => notification.id,
"is_seen" => 0,
"notice" =>
ActivityView.render("activity.json", %{activity: notification.activity, for: user}),
"ntype" => "repeat"
}
assert represented ==
NotificationView.render("notification.json", %{notification: notification, for: user})
end
test "A like notification" do
note_activity = insert(:note_activity)
user = User.get_cached_by_ap_id(note_activity.data["actor"])
liker = insert(:user)
{:ok, _activity} = TwitterAPI.fav(liker, note_activity.id)
[notification] = Notification.for_user(user)
represented = %{
"created_at" => notification.inserted_at |> Utils.format_naive_asctime(),
"from_profile" => UserView.render("show.json", %{user: liker, for: user}),
"id" => notification.id,
"is_seen" => 0,
"notice" =>
ActivityView.render("activity.json", %{activity: notification.activity, for: user}),
"ntype" => "like"
}
assert represented ==
NotificationView.render("notification.json", %{notification: notification, for: user})
end
end

View file

@ -1,323 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.UserViewTest do
use Pleroma.DataCase
alias Pleroma.User
alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Web.TwitterAPI.UserView
import Pleroma.Factory
setup do
user = insert(:user, bio: "<span>Here's some html</span>")
[user: user]
end
test "A user with only a nickname", %{user: user} do
user = %{user | name: nil, nickname: "scarlett@catgirl.science"}
represented = UserView.render("show.json", %{user: user})
assert represented["name"] == user.nickname
assert represented["name_html"] == user.nickname
end
test "A user with an avatar object", %{user: user} do
image = "image"
user = %{user | avatar: %{"url" => [%{"href" => image}]}}
represented = UserView.render("show.json", %{user: user})
assert represented["profile_image_url"] == image
end
test "A user with emoji in username" do
expected =
"<img class=\"emoji\" alt=\"karjalanpiirakka\" title=\"karjalanpiirakka\" src=\"/file.png\" /> man"
user =
insert(:user, %{
info: %{
source_data: %{
"tag" => [
%{
"type" => "Emoji",
"icon" => %{"url" => "/file.png"},
"name" => ":karjalanpiirakka:"
}
]
}
},
name: ":karjalanpiirakka: man"
})
represented = UserView.render("show.json", %{user: user})
assert represented["name_html"] == expected
end
test "A user" do
note_activity = insert(:note_activity)
user = User.get_cached_by_ap_id(note_activity.data["actor"])
{:ok, user} = User.update_note_count(user)
follower = insert(:user)
second_follower = insert(:user)
User.follow(follower, user)
User.follow(second_follower, user)
User.follow(user, follower)
{:ok, user} = User.update_follower_count(user)
Cachex.put(:user_cache, "user_info:#{user.id}", User.user_info(Repo.get!(User, user.id)))
image = "http://localhost:4001/images/avi.png"
banner = "http://localhost:4001/images/banner.png"
represented = %{
"id" => user.id,
"name" => user.name,
"screen_name" => user.nickname,
"name_html" => user.name,
"description" => HtmlSanitizeEx.strip_tags(user.bio |> String.replace("<br>", "\n")),
"description_html" => HtmlSanitizeEx.basic_html(user.bio),
"created_at" => user.inserted_at |> Utils.format_naive_asctime(),
"favourites_count" => 0,
"statuses_count" => 1,
"friends_count" => 1,
"followers_count" => 2,
"profile_image_url" => image,
"profile_image_url_https" => image,
"profile_image_url_profile_size" => image,
"profile_image_url_original" => image,
"following" => false,
"follows_you" => false,
"statusnet_blocking" => false,
"statusnet_profile_url" => user.ap_id,
"cover_photo" => banner,
"background_image" => nil,
"is_local" => true,
"locked" => false,
"hide_follows" => false,
"hide_followers" => false,
"fields" => [],
"pleroma" => %{
"confirmation_pending" => false,
"tags" => [],
"skip_thread_containment" => false
},
"rights" => %{"admin" => false, "delete_others_notice" => false},
"role" => "member"
}
assert represented == UserView.render("show.json", %{user: user})
end
test "User exposes settings for themselves and only for themselves", %{user: user} do
as_user = UserView.render("show.json", %{user: user, for: user})
assert as_user["default_scope"] == user.info.default_scope
assert as_user["no_rich_text"] == user.info.no_rich_text
assert as_user["pleroma"]["notification_settings"] == user.info.notification_settings
as_stranger = UserView.render("show.json", %{user: user})
refute as_stranger["default_scope"]
refute as_stranger["no_rich_text"]
refute as_stranger["pleroma"]["notification_settings"]
end
test "A user for a given other follower", %{user: user} do
follower = insert(:user, %{following: [User.ap_followers(user)]})
{:ok, user} = User.update_follower_count(user)
image = "http://localhost:4001/images/avi.png"
banner = "http://localhost:4001/images/banner.png"
represented = %{
"id" => user.id,
"name" => user.name,
"screen_name" => user.nickname,
"name_html" => user.name,
"description" => HtmlSanitizeEx.strip_tags(user.bio |> String.replace("<br>", "\n")),
"description_html" => HtmlSanitizeEx.basic_html(user.bio),
"created_at" => user.inserted_at |> Utils.format_naive_asctime(),
"favourites_count" => 0,
"statuses_count" => 0,
"friends_count" => 0,
"followers_count" => 1,
"profile_image_url" => image,
"profile_image_url_https" => image,
"profile_image_url_profile_size" => image,
"profile_image_url_original" => image,
"following" => true,
"follows_you" => false,
"statusnet_blocking" => false,
"statusnet_profile_url" => user.ap_id,
"cover_photo" => banner,
"background_image" => nil,
"is_local" => true,
"locked" => false,
"hide_follows" => false,
"hide_followers" => false,
"fields" => [],
"pleroma" => %{
"confirmation_pending" => false,
"tags" => [],
"skip_thread_containment" => false
},
"rights" => %{"admin" => false, "delete_others_notice" => false},
"role" => "member"
}
assert represented == UserView.render("show.json", %{user: user, for: follower})
end
test "A user that follows you", %{user: user} do
follower = insert(:user)
{:ok, follower} = User.follow(follower, user)
{:ok, user} = User.update_follower_count(user)
image = "http://localhost:4001/images/avi.png"
banner = "http://localhost:4001/images/banner.png"
represented = %{
"id" => follower.id,
"name" => follower.name,
"screen_name" => follower.nickname,
"name_html" => follower.name,
"description" => HtmlSanitizeEx.strip_tags(follower.bio |> String.replace("<br>", "\n")),
"description_html" => HtmlSanitizeEx.basic_html(follower.bio),
"created_at" => follower.inserted_at |> Utils.format_naive_asctime(),
"favourites_count" => 0,
"statuses_count" => 0,
"friends_count" => 1,
"followers_count" => 0,
"profile_image_url" => image,
"profile_image_url_https" => image,
"profile_image_url_profile_size" => image,
"profile_image_url_original" => image,
"following" => false,
"follows_you" => true,
"statusnet_blocking" => false,
"statusnet_profile_url" => follower.ap_id,
"cover_photo" => banner,
"background_image" => nil,
"is_local" => true,
"locked" => false,
"hide_follows" => false,
"hide_followers" => false,
"fields" => [],
"pleroma" => %{
"confirmation_pending" => false,
"tags" => [],
"skip_thread_containment" => false
},
"rights" => %{"admin" => false, "delete_others_notice" => false},
"role" => "member"
}
assert represented == UserView.render("show.json", %{user: follower, for: user})
end
test "a user that is a moderator" do
user = insert(:user, %{info: %{is_moderator: true}})
represented = UserView.render("show.json", %{user: user, for: user})
assert represented["rights"]["delete_others_notice"]
assert represented["role"] == "moderator"
end
test "a user that is a admin" do
user = insert(:user, %{info: %{is_admin: true}})
represented = UserView.render("show.json", %{user: user, for: user})
assert represented["rights"]["admin"]
assert represented["role"] == "admin"
end
test "A moderator with hidden role for another user", %{user: user} do
admin = insert(:user, %{info: %{is_moderator: true, show_role: false}})
represented = UserView.render("show.json", %{user: admin, for: user})
assert represented["role"] == nil
end
test "An admin with hidden role for another user", %{user: user} do
admin = insert(:user, %{info: %{is_admin: true, show_role: false}})
represented = UserView.render("show.json", %{user: admin, for: user})
assert represented["role"] == nil
end
test "A regular user for the admin", %{user: user} do
admin = insert(:user, %{info: %{is_admin: true}})
represented = UserView.render("show.json", %{user: user, for: admin})
assert represented["pleroma"]["deactivated"] == false
end
test "A blocked user for the blocker" do
user = insert(:user)
blocker = insert(:user)
User.block(blocker, user)
image = "http://localhost:4001/images/avi.png"
banner = "http://localhost:4001/images/banner.png"
represented = %{
"id" => user.id,
"name" => user.name,
"screen_name" => user.nickname,
"name_html" => user.name,
"description" => HtmlSanitizeEx.strip_tags(user.bio |> String.replace("<br>", "\n")),
"description_html" => HtmlSanitizeEx.basic_html(user.bio),
"created_at" => user.inserted_at |> Utils.format_naive_asctime(),
"favourites_count" => 0,
"statuses_count" => 0,
"friends_count" => 0,
"followers_count" => 0,
"profile_image_url" => image,
"profile_image_url_https" => image,
"profile_image_url_profile_size" => image,
"profile_image_url_original" => image,
"following" => false,
"follows_you" => false,
"statusnet_blocking" => true,
"statusnet_profile_url" => user.ap_id,
"cover_photo" => banner,
"background_image" => nil,
"is_local" => true,
"locked" => false,
"hide_follows" => false,
"hide_followers" => false,
"fields" => [],
"pleroma" => %{
"confirmation_pending" => false,
"tags" => [],
"skip_thread_containment" => false
},
"rights" => %{"admin" => false, "delete_others_notice" => false},
"role" => "member"
}
blocker = User.get_cached_by_id(blocker.id)
assert represented == UserView.render("show.json", %{user: user, for: blocker})
end
test "a user with mastodon fields" do
fields = [
%{
"name" => "Pronouns",
"value" => "she/her"
},
%{
"name" => "Website",
"value" => "https://example.org/"
}
]
user =
insert(:user, %{
info: %{
source_data: %{
"attachment" =>
Enum.map(fields, fn field -> Map.put(field, "type", "PropertyValue") end)
}
}
})
userview = UserView.render("show.json", %{user: user})
assert userview["fields"] == fields
end
end