mobilizon/test/graphql/resolvers/discussion_test.exs

559 lines
16 KiB
Elixir

defmodule Mobilizon.GraphQL.Resolvers.DiscussionTest do
use Mobilizon.Web.ConnCase
import Mobilizon.Factory
alias Mobilizon.Actors.Actor
alias Mobilizon.Discussions
alias Mobilizon.Discussions.{Comment, Discussion}
alias Mobilizon.GraphQL.AbsintheHelpers
@comment_text "What do you think?"
@discussion_title "Hey, I'm a title!"
setup %{conn: conn} do
user = insert(:user)
actor = insert(:actor, user: user)
group = insert(:group)
insert(:member, role: :member, parent: group, actor: actor)
{:ok, conn: conn, actor: actor, user: user, group: group}
end
@discussion_fields_fragment """
fragment DiscussionFields on Discussion {
id
title
slug
lastComment {
id
text
insertedAt
updatedAt
actor {
id
}
}
actor {
id
domain
name
preferredUsername
}
creator {
id
domain
name
preferredUsername
}
}
"""
describe "create a discussion" do
@create_discussion_mutation """
mutation createDiscussion($title: String!, $actorId: ID!, $text: String!) {
createDiscussion(title: $title, text: $text, actorId: $actorId) {
...DiscussionFields
}
}
#{@discussion_fields_fragment}
"""
test "create_discussion/3 creates a discussion", %{
conn: conn,
actor: actor,
user: user,
group: group
} do
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @create_discussion_mutation,
variables: %{text: @comment_text, actorId: group.id, title: @discussion_title}
)
assert res["errors"] == nil
assert res["data"]["createDiscussion"]["actor"]["id"] == to_string(group.id)
assert res["data"]["createDiscussion"]["creator"]["id"] == to_string(actor.id)
assert res["data"]["createDiscussion"]["title"] == @discussion_title
assert res["data"]["createDiscussion"]["lastComment"]["text"] == @comment_text
assert res["data"]["createDiscussion"]["lastComment"]["actor"]["id"] ==
to_string(actor.id)
end
test "create_discussion/3 doesn't work if the actor is not a member", %{
conn: conn,
group: group
} do
user = insert(:user)
insert(:actor, user: user)
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @create_discussion_mutation,
variables: %{text: @comment_text, actorId: group.id, title: @discussion_title}
)
assert hd(res["errors"])["code"] == "unauthorized"
end
test "create_discussion/3 doesn't work if the actor is not an approved member", %{
conn: conn,
group: group
} do
user = insert(:user)
actor = insert(:actor, user: user)
insert(:member, role: :invited, actor: actor, parent: group)
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @create_discussion_mutation,
variables: %{text: @comment_text, actorId: group.id, title: @discussion_title}
)
assert hd(res["errors"])["code"] == "unauthorized"
end
test "create_discussion/3 doesn't work if the user isn't logged-in", %{
conn: conn,
group: group
} do
res =
conn
|> AbsintheHelpers.graphql_query(
query: @create_discussion_mutation,
variables: %{text: @comment_text, actorId: group.id, title: @discussion_title}
)
assert hd(res["errors"])["code"] == "unauthenticated"
end
end
describe "reply to a discussion" do
@reply_to_discussion_mutation """
mutation replyToDiscussion($discussionId: ID!, $text: String!) {
replyToDiscussion(discussionId: $discussionId, text: $text) {
...DiscussionFields
}
}
#{@discussion_fields_fragment}
"""
@reply_text "I agree with that."
test "reply_to_discussion/3 replies to a discussion", %{
conn: conn,
actor: actor,
group: group
} do
%Discussion{id: discussion_id} = insert_discussion(group, actor)
user = insert(:user)
actor2 = insert(:actor, user: user)
insert(:member, role: :member, parent: group, actor: actor2)
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @reply_to_discussion_mutation,
variables: %{text: @reply_text, discussionId: discussion_id}
)
assert res["errors"] == nil
assert res["data"]["replyToDiscussion"]["actor"]["id"] == to_string(group.id)
assert res["data"]["replyToDiscussion"]["creator"]["id"] == to_string(actor.id)
assert res["data"]["replyToDiscussion"]["lastComment"]["actor"]["id"] ==
to_string(actor2.id)
assert res["data"]["replyToDiscussion"]["lastComment"]["text"] == @reply_text
end
end
describe "Update a discussion" do
@update_a_discussion_mutation """
mutation updateDiscussion($discussionId: ID!, $title: String!) {
updateDiscussion(discussionId: $discussionId, title: $title) {
...DiscussionFields
}
}
#{@discussion_fields_fragment}
"""
@updated_title "New title for discussion"
test "update_a_discussion/3 updates a discussion as original creator", %{
conn: conn,
user: user,
actor: actor,
group: group
} do
%Discussion{id: discussion_id} = insert_discussion(group, actor)
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @update_a_discussion_mutation,
variables: %{title: @updated_title, discussionId: discussion_id}
)
assert res["errors"] == nil
assert res["data"]["updateDiscussion"]["title"] == @updated_title
end
test "update_a_discussion/3 doesn't update a discussion if not member", %{
conn: conn,
actor: actor,
group: group
} do
%Discussion{id: discussion_id} = insert_discussion(group, actor)
user = insert(:user)
actor2 = insert(:actor, user: user)
insert(:member, role: :invited, parent: group, actor: actor2)
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @update_a_discussion_mutation,
variables: %{title: @updated_title, discussionId: discussion_id}
)
assert hd(res["errors"])["code"] == "unauthorized"
end
test "update_a_discussion/3 doesn't update a discussion if not logged in", %{
conn: conn,
actor: actor,
group: group
} do
%Discussion{id: discussion_id} = insert_discussion(group, actor)
res =
conn
|> AbsintheHelpers.graphql_query(
query: @update_a_discussion_mutation,
variables: %{title: @updated_title, discussionId: discussion_id}
)
assert hd(res["errors"])["code"] == "unauthenticated"
end
end
describe "Delete a discussion" do
@delete_discussion_mutation """
mutation deleteDiscussion($discussionId: ID!) {
deleteDiscussion(discussionId: $discussionId) {
id
}
}
"""
test "delete_discussion/3 deletes a discussion", %{
conn: conn,
user: user,
actor: actor,
group: group
} do
%Discussion{id: discussion_id} = insert_discussion(group, actor)
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @delete_discussion_mutation,
variables: %{discussionId: discussion_id}
)
assert res["errors"] == nil
assert res["data"]["deleteDiscussion"]["id"] == to_string(discussion_id)
assert nil == Discussions.get_discussion(discussion_id)
end
test "delete_discussion/3 doesn't delete a discussion if not member", %{
conn: conn,
actor: actor,
group: group
} do
%Discussion{id: discussion_id} = insert_discussion(group, actor)
user = insert(:user)
actor2 = insert(:actor, user: user)
insert(:member, role: :invited, parent: group, actor: actor2)
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @delete_discussion_mutation,
variables: %{discussionId: discussion_id}
)
assert hd(res["errors"])["code"] == "unauthorized"
refute nil == Discussions.get_discussion(discussion_id)
end
test "delete_discussion/3 doesn't delete a discussion if not logged in", %{
conn: conn,
actor: actor,
group: group
} do
%Discussion{id: discussion_id} = insert_discussion(group, actor)
res =
conn
|> AbsintheHelpers.graphql_query(
query: @delete_discussion_mutation,
variables: %{discussionId: discussion_id}
)
assert hd(res["errors"])["code"] == "unauthenticated"
refute nil == Discussions.get_discussion(discussion_id)
end
# test "create_comment/3 doesn't allow creating events if it's disabled", %{
# conn: conn,
# actor: actor,
# user: user,
# event: event
# } do
# {:ok, %Event{options: %EventOptions{comment_moderation: :closed}}} =
# Events.update_event(event, %{options: %{comment_moderation: :closed}})
# res =
# conn
# |> auth_conn(user)
# |> AbsintheHelpers.graphql_query(
# query: @create_comment_mutation,
# variables: %{text: @comment_text, eventId: event.id}
# )
# assert hd(res["errors"])["message"] ==
# "You don't have permission to do this"
# end
# test "create_comment/3 allows creating events if it's disabled but we're the organizer", %{
# conn: conn,
# actor: actor,
# user: user
# } do
# event = insert(:event, organizer_actor: actor, options: %{comment_moderation: :closed})
# res =
# conn
# |> auth_conn(user)
# |> AbsintheHelpers.graphql_query(
# query: @create_comment_mutation,
# variables: %{text: @comment_text, eventId: event.id}
# )
# assert is_nil(res["errors"])
# assert res["data"]["createComment"]["text"] == @comment_text
# end
# test "create_comment/3 requires that the user needs to be authenticated", %{
# conn: conn,
# event: event
# } do
# actor = insert(:actor)
# res =
# conn
# |> AbsintheHelpers.graphql_query(
# query: @create_comment_mutation,
# variables: %{text: @comment_text, eventId: event.id}
# )
# 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)
# res =
# conn
# |> auth_conn(user)
# |> AbsintheHelpers.graphql_query(
# query: @create_comment_mutation,
# variables: %{
# text: @comment_text,
# eventId: event.id,
# inReplyToCommentId: comment.id
# }
# )
# assert is_nil(res["errors"])
# assert res["data"]["createComment"]["text"] == @comment_text
# uuid = res["data"]["createComment"]["uuid"]
# assert res["data"]["createComment"]["inReplyToComment"]["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!) {
# deleteComment(commentId: $commentId) {
# 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}
# )
# assert hd(res["errors"])["message"] ==
# "You are not allowed to delete a comment if not connected"
# # Change the current actor for user
# actor2 = insert(:actor, user: user)
# Mobilizon.Users.update_user_default_actor(user, actor2)
# res =
# conn
# |> auth_conn(user)
# |> AbsintheHelpers.graphql_query(
# query: @delete_comment,
# variables: %{commentId: comment.id}
# )
# assert hd(res["errors"])["message"] ==
# "You cannot delete this comment"
# Mobilizon.Users.update_user_default_actor(user, actor)
# res =
# conn
# |> auth_conn(user)
# |> AbsintheHelpers.graphql_query(
# query: @delete_comment,
# variables: %{commentId: comment.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}
# )
# 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
@spec insert_discussion(Actor.t(), Actor.t()) :: Discussion.t()
defp insert_discussion(%Actor{type: :Group} = group, %Actor{} = actor) do
%Comment{id: comment_id} = comment = insert(:comment)
%Discussion{id: discussion_id} =
discussion = insert(:discussion, creator: actor, actor: group)
Discussions.update_comment(comment, %{discussion_id: discussion_id})
{:ok, %Discussion{} = discussion} =
Discussions.update_discussion(discussion, %{last_comment_id: comment_id})
discussion
end
end