Introduce comments below events
Also add tomstones Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
@@ -581,7 +581,7 @@ defmodule Mobilizon.EventsTest do
|
||||
test "delete_comment/1 deletes the comment" do
|
||||
comment = insert(:comment)
|
||||
assert {:ok, %Comment{}} = Events.delete_comment(comment)
|
||||
assert_raise Ecto.NoResultsError, fn -> Events.get_comment!(comment.id) end
|
||||
refute is_nil(Events.get_comment!(comment.id).deleted_at)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -148,13 +148,14 @@ defmodule Mobilizon.Service.ActivityPub.ActivityPubTest do
|
||||
test "it creates a delete activity and deletes the original comment" do
|
||||
comment = insert(:comment)
|
||||
comment = Events.get_comment_from_url_with_preload!(comment.url)
|
||||
assert is_nil(Events.get_comment_from_url(comment.url).deleted_at)
|
||||
{:ok, delete, _} = ActivityPub.delete(comment)
|
||||
|
||||
assert delete.data["type"] == "Delete"
|
||||
assert delete.data["actor"] == comment.actor.url
|
||||
assert delete.data["object"] == comment.url
|
||||
|
||||
assert Events.get_comment_from_url(comment.url) == nil
|
||||
refute is_nil(Events.get_comment_from_url(comment.url).deleted_at)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -91,31 +91,50 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
|
||||
# assert activity == returned_activity.data
|
||||
# end
|
||||
|
||||
# test "it fetches replied-to activities if we don't have them" do
|
||||
# data =
|
||||
# File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
# |> Jason.decode!()
|
||||
test "it fetches replied-to activities if we don't have them" do
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Jason.decode!()
|
||||
|
||||
# object =
|
||||
# data["object"]
|
||||
# |> Map.put("inReplyTo", "https://shitposter.club/notice/2827873")
|
||||
object =
|
||||
data["object"]
|
||||
|> Map.put("inReplyTo", "https://blob.cat/objects/02fdea3d-932c-4348-9ecb-3f9eb3fbdd94")
|
||||
|
||||
# data =
|
||||
# data
|
||||
# |> Map.put("object", object)
|
||||
data =
|
||||
data
|
||||
|> Map.put("object", object)
|
||||
|
||||
# {:ok, returned_activity, _} = Transmogrifier.handle_incoming(data)
|
||||
{:ok, returned_activity, _} = Transmogrifier.handle_incoming(data)
|
||||
|
||||
# assert activity =
|
||||
# Activity.get_create_activity_by_object_ap_id(
|
||||
# "tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment"
|
||||
# )
|
||||
%Comment{} =
|
||||
origin_comment =
|
||||
Events.get_comment_from_url(
|
||||
"https://blob.cat/objects/02fdea3d-932c-4348-9ecb-3f9eb3fbdd94"
|
||||
)
|
||||
|
||||
# assert returned_activity.data["object"]["inReplyToAtomUri"] ==
|
||||
# "https://shitposter.club/notice/2827873"
|
||||
assert returned_activity.data["object"]["inReplyTo"] ==
|
||||
"https://blob.cat/objects/02fdea3d-932c-4348-9ecb-3f9eb3fbdd94"
|
||||
|
||||
# assert returned_activity.data["object"]["inReplyToStatusId"] == activity.id
|
||||
# end
|
||||
assert returned_activity.data["object"]["inReplyTo"] == origin_comment.url
|
||||
end
|
||||
|
||||
test "it does not crash if the object in inReplyTo can't be fetched" do
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|
||||
object =
|
||||
data["object"]
|
||||
|> Map.put("inReplyTo", "https://404.site/whatever")
|
||||
|
||||
data =
|
||||
data
|
||||
|> Map.put("object", object)
|
||||
|
||||
assert ExUnit.CaptureLog.capture_log([level: :warn], fn ->
|
||||
{:ok, _returned_activity, _entity} = Transmogrifier.handle_incoming(data)
|
||||
end) =~ "[warn] Parent object is something we don't handle"
|
||||
end
|
||||
|
||||
test "it works for incoming notices" do
|
||||
use_cassette "activity_pub/mastodon_post_activity" do
|
||||
@@ -440,10 +459,11 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
|
||||
|> Map.put("actor", actor_url)
|
||||
|
||||
assert Events.get_comment_from_url(comment_url)
|
||||
assert is_nil(Events.get_comment_from_url(comment_url).deleted_at)
|
||||
|
||||
{:ok, %Activity{local: false}, _} = Transmogrifier.handle_incoming(data)
|
||||
|
||||
refute Events.get_comment_from_url(comment_url)
|
||||
refute is_nil(Events.get_comment_from_url(comment_url).deleted_at)
|
||||
end
|
||||
|
||||
# TODO : make me ASAP
|
||||
|
||||
@@ -117,37 +117,32 @@ defmodule Mobilizon.Service.FormatterTest do
|
||||
describe "add_user_links" do
|
||||
test "gives a replacement for user links, using local nicknames in user links text" do
|
||||
text = "@gsimg According to @archa_eme_, that is @daggsy. Also hello @archaeme@archae.me"
|
||||
gsimg = insert(:actor, preferred_username: "gsimg")
|
||||
_gsimg = insert(:actor, preferred_username: "gsimg")
|
||||
|
||||
archaeme =
|
||||
_archaeme =
|
||||
insert(:actor, preferred_username: "archa_eme_", url: "https://archeme/@archa_eme_")
|
||||
|
||||
archaeme_remote = insert(:actor, preferred_username: "archaeme", domain: "archae.me")
|
||||
_archaeme_remote = insert(:actor, preferred_username: "archaeme", domain: "archae.me")
|
||||
|
||||
{text, mentions, []} = Formatter.linkify(text)
|
||||
|
||||
assert length(mentions) == 3
|
||||
|
||||
expected_text =
|
||||
"<span class='h-card'><a data-user='#{gsimg.id}' class='u-url mention' href='#{gsimg.url}'>@<span>gsimg</span></a></span> According to <span class='h-card'><a data-user='#{
|
||||
archaeme.id
|
||||
}' class='u-url mention' href='#{"https://archeme/@archa_eme_"}'>@<span>archa_eme_</span></a></span>, that is @daggsy. Also hello <span class='h-card'><a data-user='#{
|
||||
archaeme_remote.id
|
||||
}' class='u-url mention' href='#{archaeme_remote.url}'>@<span>archaeme</span></a></span>"
|
||||
"<span class='h-card mention'>@<span>gsimg</span></span> According to <span class='h-card mention'>@<span>archa_eme_</span></span>, that is @daggsy. Also hello <span class='h-card mention'>@<span>archaeme</span></span>"
|
||||
|
||||
assert expected_text == text
|
||||
end
|
||||
|
||||
test "gives a replacement for single-character local nicknames" do
|
||||
text = "@o hi"
|
||||
o = insert(:actor, preferred_username: "o")
|
||||
_o = insert(:actor, preferred_username: "o")
|
||||
|
||||
{text, mentions, []} = Formatter.linkify(text)
|
||||
|
||||
assert length(mentions) == 1
|
||||
|
||||
expected_text =
|
||||
"<span class='h-card'><a data-user='#{o.id}' class='u-url mention' href='#{o.url}'>@<span>o</span></a></span> hi"
|
||||
expected_text = "<span class='h-card mention'>@<span>o</span></span> hi"
|
||||
|
||||
assert expected_text == text
|
||||
end
|
||||
|
||||
@@ -7,7 +7,6 @@ defmodule MobilizonWeb.API.ReportTest do
|
||||
alias Mobilizon.Events.{Comment, Event}
|
||||
alias Mobilizon.Reports.{Note, Report}
|
||||
alias Mobilizon.Service.ActivityPub.Activity
|
||||
alias Mobilizon.Service.Formatter
|
||||
alias Mobilizon.Users
|
||||
alias Mobilizon.Users.User
|
||||
|
||||
@@ -24,11 +23,12 @@ defmodule MobilizonWeb.API.ReportTest do
|
||||
|
||||
assert {:ok, %Activity{} = flag_activity, _} =
|
||||
Reports.report(%{
|
||||
reporter_actor_id: reporter_id,
|
||||
reported_actor_id: reported_id,
|
||||
reporter_id: reporter_id,
|
||||
reported_id: reported_id,
|
||||
content: comment,
|
||||
event_id: event_id,
|
||||
comments_ids: []
|
||||
comments_ids: [],
|
||||
local: true
|
||||
})
|
||||
|
||||
assert %Activity{
|
||||
@@ -37,8 +37,7 @@ defmodule MobilizonWeb.API.ReportTest do
|
||||
"type" => "Flag",
|
||||
"cc" => [],
|
||||
"content" => ^comment,
|
||||
"object" => [^reported_url, ^event_url],
|
||||
"state" => "open"
|
||||
"object" => [^reported_url, ^event_url]
|
||||
}
|
||||
} = flag_activity
|
||||
end
|
||||
@@ -57,8 +56,8 @@ defmodule MobilizonWeb.API.ReportTest do
|
||||
|
||||
assert {:ok, %Activity{} = flag_activity, _} =
|
||||
Reports.report(%{
|
||||
reporter_actor_id: reporter_id,
|
||||
reported_actor_id: reported_id,
|
||||
reporter_id: reporter_id,
|
||||
reported_id: reported_id,
|
||||
content: comment,
|
||||
event_id: nil,
|
||||
comments_ids: [comment_1_id, comment_2_id]
|
||||
@@ -68,10 +67,11 @@ defmodule MobilizonWeb.API.ReportTest do
|
||||
actor: ^reporter_url,
|
||||
data: %{
|
||||
"type" => "Flag",
|
||||
"cc" => [],
|
||||
"content" => ^comment,
|
||||
"object" => [^reported_url, ^comment_1_url, ^comment_2_url],
|
||||
"state" => "open"
|
||||
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
|
||||
"cc" => [],
|
||||
"actor" => ^reporter_url
|
||||
}
|
||||
} = flag_activity
|
||||
end
|
||||
@@ -87,16 +87,16 @@ defmodule MobilizonWeb.API.ReportTest do
|
||||
_comment_2 = insert(:comment, actor: reported)
|
||||
|
||||
comment = "This is really not acceptable, remote admin I don't know"
|
||||
encoded_comment = Formatter.html_escape(comment, "text/plain")
|
||||
encoded_comment = HtmlSanitizeEx.strip_tags(comment)
|
||||
|
||||
assert {:ok, %Activity{} = flag_activity, _} =
|
||||
Reports.report(%{
|
||||
reporter_actor_id: reporter_id,
|
||||
reported_actor_id: reported_id,
|
||||
reporter_id: reporter_id,
|
||||
reported_id: reported_id,
|
||||
content: comment,
|
||||
event_id: nil,
|
||||
comments_ids: [comment_1_id, comment_2_id],
|
||||
forward: true
|
||||
local: false
|
||||
})
|
||||
|
||||
assert %Activity{
|
||||
@@ -107,8 +107,10 @@ defmodule MobilizonWeb.API.ReportTest do
|
||||
"cc" => [^reported_url],
|
||||
"content" => ^encoded_comment,
|
||||
"object" => [^reported_url, ^comment_1_url, ^comment_2_url],
|
||||
"state" => "open"
|
||||
}
|
||||
"to" => ["https://www.w3.org/ns/activitystreams#Public"]
|
||||
},
|
||||
local: true,
|
||||
recipients: ["https://www.w3.org/ns/activitystreams#Public", ^reported_url]
|
||||
} = flag_activity
|
||||
end
|
||||
|
||||
@@ -120,8 +122,8 @@ defmodule MobilizonWeb.API.ReportTest do
|
||||
|
||||
assert {:ok, %Activity{} = flag_activity, %Report{id: report_id} = _report} =
|
||||
Reports.report(%{
|
||||
reporter_actor_id: reporter_id,
|
||||
reported_actor_id: reported_id,
|
||||
reporter_id: reporter_id,
|
||||
reported_id: reported_id,
|
||||
content: "This is not a nice thing",
|
||||
event_id: nil,
|
||||
comments_ids: [comment_1_id],
|
||||
@@ -146,8 +148,8 @@ defmodule MobilizonWeb.API.ReportTest do
|
||||
|
||||
assert {:ok, %Activity{} = flag_activity, %Report{id: report_id} = _report} =
|
||||
Reports.report(%{
|
||||
reporter_actor_id: reporter_id,
|
||||
reported_actor_id: reported_id,
|
||||
reporter_id: reporter_id,
|
||||
reported_id: reported_id,
|
||||
content: "This is not a nice thing",
|
||||
event_id: nil,
|
||||
comments_ids: [comment_1_id],
|
||||
|
||||
@@ -8,12 +8,42 @@ defmodule MobilizonWeb.Resolvers.CommentResolverTest do
|
||||
setup %{conn: conn} do
|
||||
user = insert(:user)
|
||||
actor = insert(:actor, user: user)
|
||||
event = insert(:event)
|
||||
|
||||
{:ok, conn: conn, actor: actor, user: user}
|
||||
{:ok, conn: conn, actor: actor, user: user, event: event}
|
||||
end
|
||||
|
||||
describe "Comment Resolver" do
|
||||
test "create_comment/3 creates a comment", %{conn: conn, actor: actor, user: user} do
|
||||
test "create_comment/3 creates a comment", %{
|
||||
conn: conn,
|
||||
actor: actor,
|
||||
user: user,
|
||||
event: event
|
||||
} do
|
||||
mutation = """
|
||||
mutation {
|
||||
createComment(
|
||||
text: "#{@comment.text}",
|
||||
actor_id: "#{actor.id}",
|
||||
event_id: "#{event.id}"
|
||||
) {
|
||||
text,
|
||||
uuid
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
res =
|
||||
conn
|
||||
|> auth_conn(user)
|
||||
|> AbsintheHelpers.graphql_query(query: mutation, variables: %{})
|
||||
|
||||
assert res["data"]["createComment"]["text"] == @comment.text
|
||||
end
|
||||
|
||||
test "create_comment/3 checks that user owns actor", %{conn: conn, user: user} do
|
||||
actor = insert(:actor)
|
||||
|
||||
mutation = """
|
||||
mutation {
|
||||
createComment(
|
||||
@@ -29,9 +59,202 @@ defmodule MobilizonWeb.Resolvers.CommentResolverTest do
|
||||
res =
|
||||
conn
|
||||
|> auth_conn(user)
|
||||
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
|
||||
|> AbsintheHelpers.graphql_query(query: mutation, variables: %{})
|
||||
|
||||
assert json_response(res, 200)["data"]["createComment"]["text"] == @comment.text
|
||||
assert hd(res["errors"])["message"] ==
|
||||
"Actor id is not owned by authenticated user"
|
||||
end
|
||||
|
||||
test "create_comment/3 requires that the user needs to be authenticated", %{conn: conn} do
|
||||
actor = insert(:actor)
|
||||
|
||||
mutation = """
|
||||
mutation {
|
||||
createComment(
|
||||
text: "#{@comment.text}",
|
||||
actor_id: "#{actor.id}"
|
||||
) {
|
||||
text,
|
||||
uuid
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
res =
|
||||
conn
|
||||
|> AbsintheHelpers.graphql_query(query: mutation, variables: %{})
|
||||
|
||||
assert hd(res["errors"])["message"] ==
|
||||
"You are not allowed to create a comment if not connected"
|
||||
end
|
||||
|
||||
test "create_comment/3 creates a reply to a comment", %{
|
||||
conn: conn,
|
||||
actor: actor,
|
||||
user: user,
|
||||
event: event
|
||||
} do
|
||||
comment = insert(:comment)
|
||||
|
||||
mutation = """
|
||||
mutation {
|
||||
createComment(
|
||||
text: "#{@comment.text}",
|
||||
actor_id: "#{actor.id}",
|
||||
event_id: "#{event.id}",
|
||||
in_reply_to_comment_id: "#{comment.id}"
|
||||
) {
|
||||
id,
|
||||
text,
|
||||
uuid,
|
||||
in_reply_to_comment {
|
||||
id,
|
||||
text
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
res =
|
||||
conn
|
||||
|> auth_conn(user)
|
||||
|> AbsintheHelpers.graphql_query(query: mutation, variables: %{})
|
||||
|
||||
assert res["errors"] == nil
|
||||
assert res["data"]["createComment"]["text"] == @comment.text
|
||||
uuid = res["data"]["createComment"]["uuid"]
|
||||
|
||||
assert res["data"]["createComment"]["in_reply_to_comment"]["id"] ==
|
||||
to_string(comment.id)
|
||||
|
||||
query = """
|
||||
query {
|
||||
thread(id: #{comment.id}) {
|
||||
text,
|
||||
uuid
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
res =
|
||||
conn
|
||||
|> auth_conn(user)
|
||||
|> AbsintheHelpers.graphql_query(query: query, variables: %{})
|
||||
|
||||
assert res["errors"] == nil
|
||||
assert res["data"]["thread"] == [%{"uuid" => uuid, "text" => @comment.text}]
|
||||
end
|
||||
|
||||
@delete_comment """
|
||||
mutation DeleteComment($commentId: ID!, $actorId: ID!) {
|
||||
deleteComment(commentId: $commentId, actorId: $actorId) {
|
||||
id,
|
||||
deletedAt
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
test "deletes a comment", %{conn: conn, user: user, actor: actor} do
|
||||
comment = insert(:comment, actor: actor)
|
||||
|
||||
res =
|
||||
conn
|
||||
|> AbsintheHelpers.graphql_query(
|
||||
query: @delete_comment,
|
||||
variables: %{commentId: comment.id, actorId: actor.id}
|
||||
)
|
||||
|
||||
assert hd(res["errors"])["message"] ==
|
||||
"You are not allowed to delete a comment if not connected"
|
||||
|
||||
actor2 = insert(:actor, user: user)
|
||||
|
||||
res =
|
||||
conn
|
||||
|> auth_conn(user)
|
||||
|> AbsintheHelpers.graphql_query(
|
||||
query: @delete_comment,
|
||||
variables: %{commentId: comment.id, actorId: actor2.id}
|
||||
)
|
||||
|
||||
assert hd(res["errors"])["message"] ==
|
||||
"You cannot delete this comment"
|
||||
|
||||
res =
|
||||
conn
|
||||
|> auth_conn(user)
|
||||
|> AbsintheHelpers.graphql_query(
|
||||
query: @delete_comment,
|
||||
variables: %{commentId: comment.id, actorId: actor.id}
|
||||
)
|
||||
|
||||
assert res["errors"] == nil
|
||||
assert res["data"]["deleteComment"]["id"] == to_string(comment.id)
|
||||
refute is_nil(res["data"]["deleteComment"]["deletedAt"])
|
||||
end
|
||||
|
||||
test "delete_comment/3 allows a comment being deleted by a moderator and creates a entry in actionLogs",
|
||||
%{
|
||||
conn: conn,
|
||||
user: _user,
|
||||
actor: _actor
|
||||
} do
|
||||
user_moderator = insert(:user, role: :moderator)
|
||||
actor_moderator = insert(:actor, user: user_moderator)
|
||||
|
||||
actor2 = insert(:actor)
|
||||
comment = insert(:comment, actor: actor2)
|
||||
|
||||
res =
|
||||
conn
|
||||
|> auth_conn(user_moderator)
|
||||
|> AbsintheHelpers.graphql_query(
|
||||
query: @delete_comment,
|
||||
variables: %{commentId: comment.id, actorId: actor_moderator.id}
|
||||
)
|
||||
|
||||
assert res["data"]["deleteComment"]["id"] == to_string(comment.id)
|
||||
|
||||
query = """
|
||||
{
|
||||
actionLogs {
|
||||
action,
|
||||
actor {
|
||||
preferredUsername
|
||||
},
|
||||
object {
|
||||
... on Report {
|
||||
id,
|
||||
status
|
||||
},
|
||||
... on ReportNote {
|
||||
content
|
||||
}
|
||||
... on Event {
|
||||
id,
|
||||
title
|
||||
},
|
||||
... on Comment {
|
||||
id,
|
||||
text
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
res =
|
||||
conn
|
||||
|> auth_conn(user_moderator)
|
||||
|> get("/api", AbsintheHelpers.query_skeleton(query, "actionLogs"))
|
||||
|
||||
refute json_response(res, 200)["errors"]
|
||||
|
||||
assert hd(json_response(res, 200)["data"]["actionLogs"]) == %{
|
||||
"action" => "COMMENT_DELETION",
|
||||
"actor" => %{"preferredUsername" => actor_moderator.preferred_username},
|
||||
"object" => %{"text" => comment.text, "id" => to_string(comment.id)}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -20,8 +20,8 @@ defmodule MobilizonWeb.Resolvers.ReportResolverTest do
|
||||
mutation = """
|
||||
mutation {
|
||||
createReport(
|
||||
reporter_actor_id: #{reporter.id},
|
||||
reported_actor_id: #{reported.id},
|
||||
reporter_id: #{reporter.id},
|
||||
reported_id: #{reported.id},
|
||||
event_id: #{event.id},
|
||||
content: "This is an issue"
|
||||
) {
|
||||
@@ -57,8 +57,8 @@ defmodule MobilizonWeb.Resolvers.ReportResolverTest do
|
||||
mutation = """
|
||||
mutation {
|
||||
createReport(
|
||||
reported_actor_id: #{reported.id},
|
||||
reporter_actor_id: 5,
|
||||
reported_id: #{reported.id},
|
||||
reporter_id: 5,
|
||||
content: "This is an issue"
|
||||
) {
|
||||
content
|
||||
|
||||
@@ -224,7 +224,7 @@ defmodule Mobilizon.Factory do
|
||||
%Mobilizon.Reports.Report{
|
||||
content: "This is problematic",
|
||||
status: :open,
|
||||
uri: "http://mobilizon.test/report/deae1020-54b8-47df-9eea-d8c0e943e57f/activity",
|
||||
url: "http://mobilizon.test/report/deae1020-54b8-47df-9eea-d8c0e943e57f/activity",
|
||||
reported: build(:actor),
|
||||
reporter: build(:actor),
|
||||
event: build(:event),
|
||||
|
||||
Reference in New Issue
Block a user