Split GraphQL as separate context

This commit is contained in:
rustra
2020-01-26 20:34:25 +01:00
parent a7acf17a4a
commit ba3ad713c0
55 changed files with 292 additions and 269 deletions

View File

@@ -0,0 +1,64 @@
defmodule Mobilizon.GraphQL.Resolvers.AddressTest do
use MobilizonWeb.ConnCase
import Mobilizon.Factory
alias Mobilizon.GraphQL.AbsintheHelpers
describe "Address Resolver" do
test "search/3 search for addresses", %{conn: conn} do
address = insert(:address, description: "10 rue Jangot, Lyon")
query = """
{
searchAddress(query: "10 Rue Jangot") {
street,
description,
geom
}
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "address"))
json_response(res, 200)["data"]["searchAddress"]
|> Enum.each(fn addr -> assert Map.get(addr, "description") == address.description end)
end
test "geocode/3 reverse geocodes coordinates", %{conn: conn} do
query = """
{
reverseGeocode(longitude: -23.01, latitude: 30.01) {
description,
geom
}
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "address"))
assert json_response(res, 200)["data"]["reverseGeocode"] |> hd |> Map.get("description") ==
"Anywhere"
query = """
{
reverseGeocode(longitude: 45.75, latitude: 4.85) {
description,
geom
}
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "address"))
assert json_response(res, 200)["data"]["reverseGeocode"] |> hd |> Map.get("description") ==
"10 rue Jangot, Lyon"
end
end
end

View File

@@ -0,0 +1,221 @@
defmodule Mobilizon.GraphQL.Resolvers.AdminTest do
use MobilizonWeb.ConnCase
import Mobilizon.Factory
alias Mobilizon.Actors.Actor
alias Mobilizon.Events.Event
alias Mobilizon.Reports.{Note, Report}
alias Mobilizon.Users.User
alias Mobilizon.Federation.ActivityPub.Relay
alias Mobilizon.GraphQL.AbsintheHelpers
alias MobilizonWeb.API
describe "Resolver: List the action logs" do
@note_content "This a note on a report"
test "list_action_logs/3 list action logs", %{conn: conn} do
%User{} = user_moderator = insert(:user, role: :moderator)
%Actor{} = moderator = insert(:actor, user: user_moderator)
%User{} = user_moderator_2 = insert(:user, role: :moderator)
%Actor{} = moderator_2 = insert(:actor, user: user_moderator_2)
%Report{} = report = insert(:report)
API.Reports.update_report_status(moderator, report, "resolved")
{:ok, %Note{} = note} = API.Reports.create_report_note(report, moderator_2, @note_content)
API.Reports.delete_report_note(note, moderator_2)
query = """
{
actionLogs {
action,
actor {
preferredUsername
},
object {
... on Report {
id,
status
},
... on ReportNote {
content
}
}
}
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "actionLogs"))
assert json_response(res, 200)["errors"] |> hd |> Map.get("message") ==
"You need to be logged-in and a moderator to list action logs"
res =
conn
|> auth_conn(user_moderator)
|> get("/api", AbsintheHelpers.query_skeleton(query, "actionLogs"))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["actionLogs"] |> length == 3
assert json_response(res, 200)["data"]["actionLogs"] == [
%{
"action" => "NOTE_DELETION",
"actor" => %{"preferredUsername" => moderator_2.preferred_username},
"object" => %{"content" => @note_content}
},
%{
"action" => "NOTE_CREATION",
"actor" => %{"preferredUsername" => moderator_2.preferred_username},
"object" => %{"content" => @note_content}
},
%{
"action" => "REPORT_UPDATE_RESOLVED",
"actor" => %{"preferredUsername" => moderator.preferred_username},
"object" => %{"id" => to_string(report.id), "status" => "RESOLVED"}
}
]
end
end
describe "Resolver: Get the dashboard statistics" do
test "get_dashboard/3 gets dashboard information", %{conn: conn} do
%Event{title: title} = insert(:event)
%User{} = user_admin = insert(:user, role: :administrator)
query = """
{
dashboard {
lastPublicEventPublished {
title
}
numberOfUsers,
numberOfComments,
numberOfEvents,
numberOfReports
}
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "actionLogs"))
assert json_response(res, 200)["errors"] |> hd |> Map.get("message") ==
"You need to be logged-in and an administrator to access dashboard statistics"
res =
conn
|> auth_conn(user_admin)
|> get("/api", AbsintheHelpers.query_skeleton(query, "actionLogs"))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["dashboard"]["lastPublicEventPublished"]["title"] ==
title
end
end
describe "Resolver: Get the list of relay followers" do
test "test list_relay_followers/3 returns relay followers", %{conn: conn} do
%User{} = user_admin = insert(:user, role: :administrator)
follower_actor =
insert(:actor,
domain: "localhost",
user: nil,
url: "http://localhost:8080/actor",
preferred_username: "instance_actor",
name: "I am an instance actor"
)
%Actor{} = relay_actor = Relay.get_actor()
insert(:follower, actor: follower_actor, target_actor: relay_actor)
query = """
{
relayFollowers {
elements {
actor {
preferredUsername,
domain,
},
approved
},
total
}
}
"""
res =
conn
|> auth_conn(user_admin)
|> AbsintheHelpers.graphql_query(query: query)
assert is_nil(res["errors"])
assert hd(res["data"]["relayFollowers"]["elements"]) == %{
"actor" => %{"preferredUsername" => "instance_actor", "domain" => "localhost"},
"approved" => false
}
end
test "test list_relay_followers/3 returns relay followings", %{conn: conn} do
%User{} = user_admin = insert(:user, role: :administrator)
%Actor{
preferred_username: following_actor_preferred_username,
domain: following_actor_domain
} =
following_actor =
insert(:actor,
domain: "localhost",
user: nil,
url: "http://localhost:8080/actor",
preferred_username: "instance_actor",
name: "I am an instance actor"
)
%Actor{} = relay_actor = Relay.get_actor()
insert(:follower, actor: relay_actor, target_actor: following_actor)
query = """
{
relayFollowings {
elements {
targetActor {
preferredUsername,
domain,
},
approved
},
total
}
}
"""
res =
conn
|> auth_conn(user_admin)
|> AbsintheHelpers.graphql_query(query: query)
assert is_nil(res["errors"])
assert hd(res["data"]["relayFollowings"]["elements"]) == %{
"targetActor" => %{
"preferredUsername" => following_actor_preferred_username,
"domain" => following_actor_domain
},
"approved" => false
}
end
end
end

View File

@@ -0,0 +1,262 @@
defmodule Mobilizon.GraphQL.Resolvers.CommentTest do
use MobilizonWeb.ConnCase
import Mobilizon.Factory
alias Mobilizon.GraphQL.AbsintheHelpers
@comment %{text: "I love this event"}
setup %{conn: conn} do
user = insert(:user)
actor = insert(:actor, user: user)
event = insert(:event)
{: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,
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(
text: "#{@comment.text}",
actor_id: "#{actor.id}"
) {
text,
uuid
}
}
"""
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(query: mutation, variables: %{})
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

View File

@@ -0,0 +1,26 @@
defmodule Mobilizon.GraphQL.Resolvers.ConfigTest do
use MobilizonWeb.ConnCase
use Bamboo.Test
alias Mobilizon.GraphQL.AbsintheHelpers
describe "Resolver: Get config" do
test "get_config/3 returns the instance config", context do
query = """
{
config {
name,
registrationsOpen
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "config"))
assert json_response(res, 200)["data"]["config"]["name"] == "Test instance"
assert json_response(res, 200)["data"]["config"]["registrationsOpen"] == true
end
end
end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,340 @@
defmodule Mobilizon.GraphQL.Resolvers.FeedTokenTest do
use MobilizonWeb.ConnCase
import Mobilizon.Factory
alias Mobilizon.GraphQL.AbsintheHelpers
setup %{conn: conn} do
user = insert(:user)
actor = insert(:actor, user: user, preferred_username: "test")
insert(:actor, user: user)
{:ok, conn: conn, actor: actor, user: user}
end
describe "Feed Token Resolver" do
test "create_feed_token/3 should create a feed token", %{conn: conn, user: user} do
actor2 = insert(:actor, user: user)
mutation = """
mutation {
createFeedToken(
actor_id: #{actor2.id},
) {
token,
actor {
id
},
user {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
token = json_response(res, 200)["data"]["createFeedToken"]["token"]
assert is_binary(token)
# TODO: Investigate why user id is a string when actor id is a number
assert json_response(res, 200)["data"]["createFeedToken"]["user"]["id"] ==
to_string(user.id)
assert json_response(res, 200)["data"]["createFeedToken"]["actor"]["id"] ==
to_string(actor2.id)
# The token is present for the user
query = """
{
loggedUser {
feedTokens {
token
}
}
}
"""
res =
conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "loggedUser"))
assert json_response(res, 200)["data"]["loggedUser"] ==
%{
"feedTokens" => [%{"token" => token}]
}
# But not for this identity
query = """
{
loggedPerson {
feedTokens {
token
}
}
}
"""
res =
conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "loggedPerson"))
assert json_response(res, 200)["data"]["loggedPerson"] ==
%{
"feedTokens" => []
}
mutation = """
mutation {
createFeedToken {
token,
user {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
token2 = json_response(res, 200)["data"]["createFeedToken"]["token"]
assert is_binary(token2)
assert is_nil(json_response(res, 200)["data"]["createFeedToken"]["actor"])
assert json_response(res, 200)["data"]["createFeedToken"]["user"]["id"] ==
to_string(user.id)
# The token is present for the user
query = """
{
loggedUser {
feedTokens {
token
}
}
}
"""
res =
conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "loggedUser"))
assert json_response(res, 200)["data"]["loggedUser"] ==
%{
"feedTokens" => [%{"token" => token}, %{"token" => token2}]
}
end
test "create_feed_token/3 should check the actor is owned by the user", %{
conn: conn,
user: user
} do
actor = insert(:actor)
mutation = """
mutation {
createFeedToken(
actor_id: #{actor.id}
) {
token
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "not owned"
end
test "delete_feed_token/3 should delete a feed token", %{
conn: conn,
user: user,
actor: actor
} do
feed_token = insert(:feed_token, user: user, actor: actor)
query = """
{
loggedPerson {
feedTokens {
token
}
}
}
"""
res =
conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "loggedPerson"))
assert json_response(res, 200)["data"]["loggedPerson"] ==
%{
"feedTokens" => [
%{
"token" => feed_token.token
}
]
}
mutation = """
mutation {
deleteFeedToken(
token: "#{feed_token.token}",
) {
actor {
id
},
user {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["deleteFeedToken"]["user"]["id"] ==
to_string(user.id)
assert json_response(res, 200)["data"]["deleteFeedToken"]["actor"]["id"] ==
to_string(actor.id)
query = """
{
loggedPerson {
feedTokens {
token
}
}
}
"""
res =
conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "loggedPerson"))
assert json_response(res, 200)["data"]["loggedPerson"] ==
%{
"feedTokens" => []
}
end
test "delete_feed_token/3 should check the user is logged in", %{conn: conn} do
mutation = """
mutation {
deleteFeedToken(
token: "random",
) {
actor {
id
}
}
}
"""
res =
conn
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "if not connected"
end
test "delete_feed_token/3 should check the correct user is logged in", %{
conn: conn,
user: user
} do
user2 = insert(:user)
feed_token = insert(:feed_token, user: user2)
mutation = """
mutation {
deleteFeedToken(
token: "#{feed_token.token}",
) {
actor {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "don't have permission"
end
test "delete_feed_token/3 should check the token is a valid UUID", %{
conn: conn,
user: user
} do
mutation = """
mutation {
deleteFeedToken(
token: "really random"
) {
actor {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "Token is not a valid UUID"
end
test "delete_feed_token/3 should check the token exists", %{
conn: conn,
user: user
} do
uuid = Ecto.UUID.generate()
mutation = """
mutation {
deleteFeedToken(
token: "#{uuid}"
) {
actor {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "does not exist"
end
end
end

View File

@@ -0,0 +1,279 @@
defmodule MobilizonWeb.Resolvers.GroupTest do
use MobilizonWeb.ConnCase
import Mobilizon.Factory
alias Mobilizon.GraphQL.AbsintheHelpers
@non_existent_username "nonexistent"
@new_group_params %{groupname: "new group"}
setup %{conn: conn} do
user = insert(:user)
actor = insert(:actor, user: user)
{:ok, conn: conn, actor: actor, user: user}
end
describe "Group Resolver" do
test "create_group/3 should check the user owns the identity", %{conn: conn, user: user} do
another_actor = insert(:actor)
mutation = """
mutation {
createGroup(
preferred_username: "#{@new_group_params.groupname}",
creator_actor_id: #{another_actor.id}
) {
preferred_username,
type
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] ==
"Creator actor id is not owned by the current user"
end
test "create_group/3 creates a group and check a group with this name does not already exist",
%{conn: conn, user: user, actor: actor} do
mutation = """
mutation {
createGroup(
preferred_username: "#{@new_group_params.groupname}",
creator_actor_id: #{actor.id}
) {
preferred_username,
type
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["data"]["createGroup"]["preferred_username"] ==
@new_group_params.groupname
assert json_response(res, 200)["data"]["createGroup"]["type"] == "GROUP"
mutation = """
mutation {
createGroup(
preferred_username: "#{@new_group_params.groupname}",
creator_actor_id: #{actor.id},
) {
preferred_username,
type
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] ==
"A group with this name already exists"
end
test "list_groups/3 returns all public or unlisted groups", context do
group = insert(:group, visibility: :unlisted)
insert(:group, visibility: :private)
query = """
{
groups {
preferredUsername,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "groups"))
assert length(json_response(res, 200)["data"]["groups"]) == 1
assert hd(json_response(res, 200)["data"]["groups"])["preferredUsername"] ==
group.preferred_username
end
test "find_group/3 returns a group by its username", context do
group = insert(:group)
query = """
{
group(preferredUsername: "#{group.preferred_username}") {
preferredUsername,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "group"))
assert json_response(res, 200)["data"]["group"]["preferredUsername"] ==
group.preferred_username
query = """
{
group(preferredUsername: "#{@non_existent_username}") {
preferredUsername,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "group"))
assert json_response(res, 200)["data"]["group"] == nil
assert hd(json_response(res, 200)["errors"])["message"] ==
"Group with name #{@non_existent_username} not found"
end
test "delete_group/3 deletes a group", %{conn: conn, user: user, actor: actor} do
group = insert(:group)
insert(:member, parent: group, actor: actor, role: :administrator)
mutation = """
mutation {
deleteGroup(
actor_id: #{actor.id},
group_id: #{group.id}
) {
id
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["deleteGroup"]["id"] == to_string(group.id)
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "not found"
end
test "delete_group/3 should check user authentication", %{conn: conn, actor: actor} do
group = insert(:group)
insert(:member, parent: group, actor: actor, role: :member)
mutation = """
mutation {
deleteGroup(
actor_id: #{actor.id},
group_id: #{group.id}
) {
id
}
}
"""
res =
conn
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "logged-in"
end
test "delete_group/3 should check the actor is owned by the user", %{
conn: conn,
user: user,
actor: actor
} do
group = insert(:group)
insert(:member, parent: group, actor: actor, role: :member)
mutation = """
mutation {
deleteGroup(
actor_id: 159,
group_id: #{group.id}
) {
id
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "not owned"
end
test "delete_group/3 should check the actor is a member of this group", %{
conn: conn,
user: user,
actor: actor
} do
group = insert(:group)
mutation = """
mutation {
deleteGroup(
actor_id: #{actor.id},
group_id: #{group.id}
) {
id
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "not a member"
end
test "delete_group/3 should check the actor is an administrator of this group", %{
conn: conn,
user: user,
actor: actor
} do
group = insert(:group)
insert(:member, parent: group, actor: actor, role: :member)
mutation = """
mutation {
deleteGroup(
actor_id: #{actor.id},
group_id: #{group.id}
) {
id
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "not an administrator"
end
end
end

View File

@@ -0,0 +1,289 @@
defmodule Mobilizon.GraphQL.Resolvers.MemberTest do
use MobilizonWeb.ConnCase
import Mobilizon.Factory
alias Mobilizon.GraphQL.AbsintheHelpers
setup %{conn: conn} do
user = insert(:user)
actor = insert(:actor, user: user, preferred_username: "test")
{:ok, conn: conn, actor: actor, user: user}
end
describe "Member Resolver" do
test "join_group/3 should create a member", %{conn: conn, user: user, actor: actor} do
group = insert(:group)
mutation = """
mutation {
joinGroup(
actor_id: #{actor.id},
group_id: #{group.id}
) {
role,
actor {
id
},
parent {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["joinGroup"]["role"] == "not_approved"
assert json_response(res, 200)["data"]["joinGroup"]["parent"]["id"] == to_string(group.id)
assert json_response(res, 200)["data"]["joinGroup"]["actor"]["id"] == to_string(actor.id)
mutation = """
mutation {
joinGroup(
actor_id: #{actor.id},
group_id: #{group.id}
) {
role
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "already a member"
end
test "join_group/3 should check the actor is owned by the user", %{
conn: conn,
user: user
} do
group = insert(:group)
mutation = """
mutation {
joinGroup(
actor_id: 1042,
group_id: #{group.id}
) {
role
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "not owned"
end
test "join_group/3 should check the group is not invite only", %{
conn: conn,
actor: actor,
user: user
} do
group = insert(:group, %{openness: :invite_only})
mutation = """
mutation {
joinGroup(
actor_id: #{actor.id},
group_id: #{group.id}
) {
role
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "cannot join this group"
end
test "join_group/3 should check the group exists", %{
conn: conn,
user: user,
actor: actor
} do
mutation = """
mutation {
joinGroup(
actor_id: #{actor.id},
group_id: 1042
) {
role
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "Group id not found"
end
test "leave_group/3 should delete a member from a group", %{
conn: conn,
user: user,
actor: actor
} do
group = insert(:group)
insert(:member, %{actor: actor, parent: group})
mutation = """
mutation {
leaveGroup(
actor_id: #{actor.id},
group_id: #{group.id}
) {
actor {
id
},
parent {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["leaveGroup"]["parent"]["id"] == to_string(group.id)
assert json_response(res, 200)["data"]["leaveGroup"]["actor"]["id"] == to_string(actor.id)
end
test "leave_group/3 should check if the member is the only administrator", %{
conn: conn,
actor: actor,
user: user
} do
group = insert(:group)
insert(:member, %{actor: actor, role: :creator, parent: group})
insert(:member, %{parent: group})
mutation = """
mutation {
leaveGroup(
actor_id: #{actor.id},
group_id: #{group.id}
) {
actor {
id
},
parent {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "only administrator"
end
test "leave_group/3 should check the user is logged in", %{conn: conn, actor: actor} do
group = insert(:group)
insert(:member, %{actor: actor, parent: group})
mutation = """
mutation {
leaveGroup(
actor_id: #{actor.id},
group_id: #{group.id}
) {
actor {
id
}
}
}
"""
res =
conn
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "logged-in"
end
test "leave_group/3 should check the actor is owned by the user", %{
conn: conn,
user: user,
actor: actor
} do
group = insert(:group)
insert(:member, %{actor: actor, parent: group})
mutation = """
mutation {
leaveGroup(
actor_id: 1042,
group_id: #{group.id}
) {
actor {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "not owned"
end
test "leave_group/3 should check the member exists", %{
conn: conn,
user: user,
actor: actor
} do
group = insert(:group)
insert(:member, %{actor: actor, parent: group})
mutation = """
mutation {
leaveGroup(
actor_id: #{actor.id},
group_id: 1042
) {
actor {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "Member not found"
end
end
end

View File

@@ -0,0 +1,920 @@
defmodule Mobilizon.GraphQL.Resolvers.ParticipantTest do
use MobilizonWeb.ConnCase
use Bamboo.Test
import Mobilizon.Factory
alias Mobilizon.Events
alias Mobilizon.GraphQL.AbsintheHelpers
alias MobilizonWeb.Email
@event %{
description: "some body",
title: "some title",
begins_on:
DateTime.utc_now()
|> DateTime.truncate(:second),
uuid: "b5126423-f1af-43e4-a923-002a03003ba4",
url: "some url",
category: "meeting",
options: %{}
}
setup %{conn: conn} do
user = insert(:user)
actor = insert(:actor, user: user, preferred_username: "test")
{:ok, conn: conn, actor: actor, user: user}
end
describe "Participant Resolver" do
test "actor_join_event/3 should create a participant", %{conn: conn, user: user, actor: actor} do
event = insert(:event)
mutation = """
mutation {
joinEvent(
actor_id: #{actor.id},
event_id: #{event.id}
) {
role,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["joinEvent"]["role"] == "PARTICIPANT"
assert json_response(res, 200)["data"]["joinEvent"]["event"]["id"] == to_string(event.id)
assert json_response(res, 200)["data"]["joinEvent"]["actor"]["id"] == to_string(actor.id)
mutation = """
mutation {
joinEvent(
actor_id: #{actor.id},
event_id: #{event.id}
) {
role
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "already a participant"
end
test "actor_join_event/3 doesn't work if the event already has too much participants", %{
conn: conn,
actor: actor
} do
event = insert(:event, options: %{maximum_attendee_capacity: 2})
insert(:participant, event: event, actor: actor, role: :creator)
insert(:participant, event: event, role: :participant)
insert(:participant, event: event, role: :not_approved)
insert(:participant, event: event, role: :rejected)
user_participant = insert(:user)
actor_participant = insert(:actor, user: user_participant)
mutation = """
mutation {
joinEvent(
actor_id: #{actor_participant.id},
event_id: #{event.id}
) {
role,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user_participant)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["joinEvent"]["role"] == "PARTICIPANT"
assert json_response(res, 200)["data"]["joinEvent"]["event"]["id"] == to_string(event.id)
assert json_response(res, 200)["data"]["joinEvent"]["actor"]["id"] ==
to_string(actor_participant.id)
user_participant_2 = insert(:user)
actor_participant_2 = insert(:actor, user: user_participant_2)
mutation = """
mutation {
joinEvent(
actor_id: #{actor_participant_2.id},
event_id: #{event.id}
) {
role,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user_participant_2)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] ==
"The event has already reached its maximum capacity"
end
test "actor_join_event/3 should check the actor is owned by the user", %{
conn: conn,
user: user
} do
event = insert(:event)
mutation = """
mutation {
joinEvent(
actor_id: 1042,
event_id: #{event.id}
) {
role
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "not owned"
end
test "actor_join_event/3 should check the event exists", %{
conn: conn,
user: user,
actor: actor
} do
mutation = """
mutation {
joinEvent(
actor_id: #{actor.id},
event_id: 1042
) {
role
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] ==
"Event with this ID \"1042\" doesn't exist"
end
test "actor_leave_event/3 should delete a participant from an event", %{
conn: conn,
user: user,
actor: actor
} do
event =
insert(:event, %{organizer_actor: actor, participant_stats: %{creator: 1, participant: 1}})
insert(:participant, %{actor: actor, event: event, role: :creator})
user2 = insert(:user)
actor2 = insert(:actor, user: user2)
participant2 = insert(:participant, %{event: event, actor: actor2, role: :participant})
mutation = """
mutation {
leaveEvent(
actor_id: #{participant2.actor.id},
event_id: #{event.id}
) {
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user2)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["leaveEvent"]["event"]["id"] == to_string(event.id)
assert json_response(res, 200)["data"]["leaveEvent"]["actor"]["id"] ==
to_string(participant2.actor.id)
query = """
{
person(id: "#{actor.id}") {
participations(eventId: "#{event.id}") {
event {
uuid,
title
},
role
}
}
}
"""
res =
conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "person"))
assert json_response(res, 200)["data"]["person"]["participations"] == [
%{
"event" => %{
"uuid" => event.uuid,
"title" => event.title
},
"role" => "CREATOR"
}
]
query = """
{
person(id: "#{actor2.id}") {
participations(eventId: "#{event.id}") {
event {
uuid,
title
},
role
}
}
}
"""
res =
conn
|> auth_conn(user2)
|> get("/api", AbsintheHelpers.query_skeleton(query, "person"))
assert json_response(res, 200)["data"]["person"]["participations"] == []
end
test "actor_leave_event/3 should check if the participant is the only creator", %{
conn: conn,
actor: actor,
user: user
} do
participant = insert(:participant, %{actor: actor})
mutation = """
mutation {
leaveEvent(
actor_id: #{participant.actor.id},
event_id: #{participant.event.id}
) {
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] ==
"You can't leave event because you're the only event creator participant"
# If we have a second participant but not an event creator
insert(:participant, %{event: participant.event, role: :participant})
mutation = """
mutation {
leaveEvent(
actor_id: #{participant.actor.id},
event_id: #{participant.event.id}
) {
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] ==
"You can't leave event because you're the only event creator participant"
end
test "actor_leave_event/3 should check the user is logged in", %{conn: conn, actor: actor} do
participant = insert(:participant, %{actor: actor})
mutation = """
mutation {
leaveEvent(
actor_id: #{participant.actor.id},
event_id: #{participant.event.id}
) {
actor {
id
}
}
}
"""
res =
conn
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "logged-in"
end
test "actor_leave_event/3 should check the actor is owned by the user", %{
conn: conn,
user: user
} do
participant = insert(:participant)
mutation = """
mutation {
leaveEvent(
actor_id: #{participant.actor.id},
event_id: #{participant.event.id}
) {
actor {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "not owned"
end
test "actor_leave_event/3 should check the participant exists", %{
conn: conn,
user: user,
actor: actor
} do
event = insert(:event)
participant = insert(:participant, %{actor: actor})
mutation = """
mutation {
leaveEvent(
actor_id: #{participant.actor.id},
event_id: #{event.id}
) {
actor {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "Participant not found"
end
test "list_participants_for_event/3 returns participants for an event", %{
conn: conn,
actor: actor,
user: user
} do
event =
@event
|> Map.put(:organizer_actor_id, actor.id)
{:ok, event} = Events.create_event(event)
query = """
{
event(uuid: "#{event.uuid}") {
participants(roles: "participant,moderator,administrator,creator", actor_id: "#{
actor.id
}") {
role,
actor {
preferredUsername
}
}
}
}
"""
res =
conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "participants"))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["event"]["participants"] == [
%{
"actor" => %{
"preferredUsername" => actor.preferred_username
},
"role" => "CREATOR"
}
]
# Adding two participants
actor2 = insert(:actor)
actor3 = insert(:actor)
# This one won't get listed (as not approved)
insert(:participant, event: event, actor: actor2, role: :not_approved)
# This one will (as a participant)
participant2 = insert(:participant, event: event, actor: actor3, role: :participant)
query = """
{
event(uuid: "#{event.uuid}") {
participants(page: 2, limit: 1, roles: "participant,moderator,administrator,creator", actorId: "#{
actor.id
}") {
role,
actor {
preferredUsername
}
}
}
}
"""
res =
conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "participants"))
sorted_participants =
json_response(res, 200)["data"]["event"]["participants"]
|> Enum.filter(&(&1["role"] == "PARTICIPANT"))
assert sorted_participants == [
%{
"actor" => %{
"preferredUsername" => participant2.actor.preferred_username
},
"role" => "PARTICIPANT"
}
]
query = """
{
event(uuid: "#{event.uuid}") {
participants(page: 1, limit: 1, roles: "participant,moderator,administrator,creator", actorId: "#{
actor.id
}") {
role,
actor {
preferredUsername
}
}
}
}
"""
res =
conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "participants"))
sorted_participants =
json_response(res, 200)["data"]["event"]["participants"]
|> Enum.sort_by(
&(&1
|> Map.get("actor")
|> Map.get("preferredUsername"))
)
assert sorted_participants == [
%{
"actor" => %{
"preferredUsername" => actor.preferred_username
},
"role" => "CREATOR"
}
]
end
test "stats_participants_for_event/3 give the number of (un)approved participants", %{
conn: conn,
actor: actor
} do
event =
@event
|> Map.put(:organizer_actor_id, actor.id)
{:ok, event} = Events.create_event(event)
query = """
{
event(uuid: "#{event.uuid}") {
uuid,
participantStats {
going,
notApproved,
rejected
}
}
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
assert json_response(res, 200)["data"]["event"]["uuid"] == to_string(event.uuid)
assert json_response(res, 200)["data"]["event"]["participantStats"]["going"] == 1
assert json_response(res, 200)["data"]["event"]["participantStats"]["notApproved"] == 0
assert json_response(res, 200)["data"]["event"]["participantStats"]["rejected"] == 0
moderator = insert(:actor)
Events.create_participant(%{
role: :moderator,
event_id: event.id,
actor_id: moderator.id
})
not_approved = insert(:actor)
Events.create_participant(%{
role: :not_approved,
event_id: event.id,
actor_id: not_approved.id
})
rejected = insert(:actor)
Events.create_participant(%{
role: :rejected,
event_id: event.id,
actor_id: rejected.id
})
query = """
{
event(uuid: "#{event.uuid}") {
uuid,
participantStats {
going,
notApproved,
rejected
}
}
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
assert json_response(res, 200)["data"]["event"]["uuid"] == to_string(event.uuid)
assert json_response(res, 200)["data"]["event"]["participantStats"]["going"] == 2
assert json_response(res, 200)["data"]["event"]["participantStats"]["notApproved"] == 1
assert json_response(res, 200)["data"]["event"]["participantStats"]["rejected"] == 1
end
end
describe "Participation role status update" do
test "update_participation/3", %{conn: conn, actor: actor, user: user} do
user_creator = insert(:user)
actor_creator = insert(:actor, user: user_creator)
event = insert(:event, join_options: :restricted, organizer_actor: actor_creator)
insert(:participant, event: event, actor: actor_creator, role: :creator)
mutation = """
mutation {
joinEvent(
actor_id: #{actor.id},
event_id: #{event.id}
) {
id,
role,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["joinEvent"]["role"] == "NOT_APPROVED"
assert json_response(res, 200)["data"]["joinEvent"]["event"]["id"] == to_string(event.id)
assert json_response(res, 200)["data"]["joinEvent"]["actor"]["id"] == to_string(actor.id)
participation_id = json_response(res, 200)["data"]["joinEvent"]["id"]
mutation = """
mutation {
updateParticipation(
id: "#{participation_id}",
role: PARTICIPANT,
moderator_actor_id: #{actor_creator.id}
) {
id,
role,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user_creator)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["updateParticipation"]["role"] == "PARTICIPANT"
assert json_response(res, 200)["data"]["updateParticipation"]["event"]["id"] ==
to_string(event.id)
assert json_response(res, 200)["data"]["updateParticipation"]["actor"]["id"] ==
to_string(actor.id)
participation = Mobilizon.Events.get_participant(participation_id)
assert_delivered_email(Email.Participation.participation_updated(user, participation))
res =
conn
|> auth_conn(user_creator)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] ==
"Participant already has role participant"
end
test "accept_participation/3 with bad parameters", %{conn: conn, actor: actor, user: user} do
user_creator = insert(:user)
actor_creator = insert(:actor, user: user_creator)
event = insert(:event, join_options: :restricted)
insert(:participant, event: event, role: :creator)
mutation = """
mutation {
joinEvent(
actor_id: #{actor.id},
event_id: #{event.id}
) {
id,
role,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["joinEvent"]["role"] == "NOT_APPROVED"
assert json_response(res, 200)["data"]["joinEvent"]["event"]["id"] == to_string(event.id)
assert json_response(res, 200)["data"]["joinEvent"]["actor"]["id"] == to_string(actor.id)
participation_id = json_response(res, 200)["data"]["joinEvent"]["id"]
mutation = """
mutation {
updateParticipation (
id: "#{participation_id}",
role: PARTICIPANT,
moderator_actor_id: #{actor_creator.id}
) {
id,
role,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user_creator)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] ==
"Provided moderator actor ID doesn't have permission on this event"
end
end
describe "reject participation" do
test "reject_participation/3", %{conn: conn, actor: actor, user: user} do
user_creator = insert(:user)
actor_creator = insert(:actor, user: user_creator)
event = insert(:event, join_options: :restricted, organizer_actor: actor_creator)
insert(:participant, event: event, actor: actor_creator, role: :creator)
mutation = """
mutation {
joinEvent(
actor_id: #{actor.id},
event_id: #{event.id}
) {
id,
role,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["joinEvent"]["role"] == "NOT_APPROVED"
assert json_response(res, 200)["data"]["joinEvent"]["event"]["id"] == to_string(event.id)
assert json_response(res, 200)["data"]["joinEvent"]["actor"]["id"] == to_string(actor.id)
participation_id = json_response(res, 200)["data"]["joinEvent"]["id"]
mutation = """
mutation {
updateParticipation(
id: "#{participation_id}",
role: REJECTED,
moderator_actor_id: #{actor_creator.id}
) {
id,
role,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user_creator)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["updateParticipation"]["id"] == participation_id
assert json_response(res, 200)["data"]["updateParticipation"]["event"]["id"] ==
to_string(event.id)
assert json_response(res, 200)["data"]["updateParticipation"]["actor"]["id"] ==
to_string(actor.id)
participation = Mobilizon.Events.get_participant(participation_id)
assert_delivered_email(Email.Participation.participation_updated(user, participation))
res =
conn
|> auth_conn(user_creator)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] ==
"Participant already has role rejected"
end
test "reject_participation/3 with bad parameters", %{conn: conn, actor: actor, user: user} do
user_creator = insert(:user)
actor_creator = insert(:actor, user: user_creator)
event = insert(:event, join_options: :restricted)
insert(:participant, event: event, role: :creator)
mutation = """
mutation {
joinEvent(
actor_id: #{actor.id},
event_id: #{event.id}
) {
id,
role,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["joinEvent"]["role"] == "NOT_APPROVED"
assert json_response(res, 200)["data"]["joinEvent"]["event"]["id"] == to_string(event.id)
assert json_response(res, 200)["data"]["joinEvent"]["actor"]["id"] == to_string(actor.id)
participation_id = json_response(res, 200)["data"]["joinEvent"]["id"]
mutation = """
mutation {
updateParticipation (
id: "#{participation_id}",
role: REJECTED,
moderator_actor_id: #{actor_creator.id}
) {
id,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user_creator)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] ==
"Provided moderator actor ID doesn't have permission on this event"
end
end
end

View File

@@ -0,0 +1,655 @@
defmodule Mobilizon.GraphQL.Resolvers.PersonTest do
use Oban.Testing, repo: Mobilizon.Storage.Repo
use MobilizonWeb.ConnCase
import Mobilizon.Factory
alias Mobilizon.Actors.Actor
alias Mobilizon.Service.Workers
alias Mobilizon.GraphQL.AbsintheHelpers
@non_existent_username "nonexistent"
describe "Person Resolver" do
test "get_person/3 returns a person by its username", context do
user = insert(:user)
actor = insert(:actor, user: user)
query = """
{
person(id: "#{actor.id}") {
preferredUsername,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "person"))
assert json_response(res, 200)["data"]["person"]["preferredUsername"] ==
actor.preferred_username
query = """
{
person(id: "6895567") {
preferredUsername,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "person"))
assert json_response(res, 200)["data"]["person"] == nil
assert hd(json_response(res, 200)["errors"])["message"] ==
"Person with ID 6895567 not found"
end
test "find_person/3 returns a person by its username", context do
user = insert(:user)
actor = insert(:actor, user: user)
query = """
{
fetchPerson(preferredUsername: "#{actor.preferred_username}") {
preferredUsername,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "person"))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["fetchPerson"]["preferredUsername"] ==
actor.preferred_username
query = """
{
fetchPerson(preferredUsername: "#{@non_existent_username}") {
preferredUsername,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "person"))
assert json_response(res, 200)["data"]["fetchPerson"] == nil
assert hd(json_response(res, 200)["errors"])["message"] ==
"Person with username #{@non_existent_username} not found"
end
test "get_current_person/3 returns the current logged-in actor", context do
user = insert(:user)
actor = insert(:actor, user: user)
query = """
{
loggedPerson {
avatar {
url
},
preferredUsername,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "logged_person"))
assert json_response(res, 200)["data"]["loggedPerson"] == nil
assert hd(json_response(res, 200)["errors"])["message"] ==
"You need to be logged-in to view current person"
res =
context.conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "logged_person"))
assert json_response(res, 200)["data"]["loggedPerson"]["preferredUsername"] ==
actor.preferred_username
assert json_response(res, 200)["data"]["loggedPerson"]["avatar"]["url"] =~
MobilizonWeb.Endpoint.url()
end
test "create_person/3 creates a new identity", context do
user = insert(:user)
actor = insert(:actor, user: user)
mutation = """
mutation {
createPerson(
preferredUsername: "new_identity",
name: "secret person",
summary: "no-one will know who I am"
) {
id,
preferredUsername
}
}
"""
res =
context.conn
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["data"]["createPerson"] == nil
assert hd(json_response(res, 200)["errors"])["message"] ==
"You need to be logged-in to create a new identity"
res =
context.conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["data"]["createPerson"]["preferredUsername"] ==
"new_identity"
query = """
{
identities {
avatar {
url
},
preferredUsername,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "identities"))
assert json_response(res, 200)["data"]["identities"] == nil
assert hd(json_response(res, 200)["errors"])["message"] ==
"You need to be logged-in to view your list of identities"
res =
context.conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "identities"))
assert json_response(res, 200)["data"]["identities"]
|> Enum.map(fn identity -> Map.get(identity, "preferredUsername") end)
|> MapSet.new() ==
MapSet.new([actor.preferred_username, "new_identity"])
end
test "create_person/3 with an avatar and an banner creates a new identity", context do
user = insert(:user)
insert(:actor, user: user)
mutation = """
mutation {
createPerson(
preferredUsername: "new_identity",
name: "secret person",
summary: "no-one will know who I am",
banner: {
picture: {
file: "landscape.jpg",
name: "irish landscape",
alt: "The beautiful atlantic way"
}
}
) {
id,
preferredUsername
avatar {
id,
url
},
banner {
id,
name,
url
}
}
}
"""
map = %{
"query" => mutation,
"landscape.jpg" => %Plug.Upload{
path: "test/fixtures/picture.png",
filename: "landscape.jpg"
}
}
res =
context.conn
|> put_req_header("content-type", "multipart/form-data")
|> post("/api", map)
assert json_response(res, 200)["data"]["createPerson"] == nil
assert hd(json_response(res, 200)["errors"])["message"] ==
"You need to be logged-in to create a new identity"
res =
context.conn
|> auth_conn(user)
|> put_req_header("content-type", "multipart/form-data")
|> post("/api", map)
assert json_response(res, 200)["data"]["createPerson"]["preferredUsername"] ==
"new_identity"
assert json_response(res, 200)["data"]["createPerson"]["banner"]["id"]
assert json_response(res, 200)["data"]["createPerson"]["banner"]["name"] ==
"The beautiful atlantic way"
assert json_response(res, 200)["data"]["createPerson"]["banner"]["url"] =~
MobilizonWeb.Endpoint.url() <> "/media/"
end
test "update_person/3 updates an existing identity", context do
user = insert(:user)
%Actor{id: person_id} = insert(:actor, user: user, preferred_username: "riri")
mutation = """
mutation {
updatePerson(
id: "#{person_id}",
name: "riri updated",
summary: "summary updated",
banner: {
picture: {
file: "landscape.jpg",
name: "irish landscape",
alt: "The beautiful atlantic way"
}
}
) {
id,
preferredUsername,
name,
summary,
avatar {
id,
url
},
banner {
id,
name,
url
}
}
}
"""
map = %{
"query" => mutation,
"landscape.jpg" => %Plug.Upload{
path: "test/fixtures/picture.png",
filename: "landscape.jpg"
}
}
res =
context.conn
|> put_req_header("content-type", "multipart/form-data")
|> post("/api", map)
assert json_response(res, 200)["data"]["updatePerson"] == nil
assert hd(json_response(res, 200)["errors"])["message"] ==
"You need to be logged-in to update an identity"
res =
context.conn
|> auth_conn(user)
|> put_req_header("content-type", "multipart/form-data")
|> post("/api", map)
res_person = json_response(res, 200)["data"]["updatePerson"]
assert res_person["preferredUsername"] == "riri"
assert res_person["name"] == "riri updated"
assert res_person["summary"] == "summary updated"
assert res_person["banner"]["id"]
assert res_person["banner"]["name"] == "The beautiful atlantic way"
assert res_person["banner"]["url"] =~ MobilizonWeb.Endpoint.url() <> "/media/"
end
test "update_person/3 should fail to update a not owned identity", context do
user1 = insert(:user)
user2 = insert(:user)
%Actor{id: person_id} = insert(:actor, user: user2, preferred_username: "riri")
mutation = """
mutation {
updatePerson(
id: "#{person_id}",
name: "riri updated",
) {
id,
}
}
"""
res =
context.conn
|> auth_conn(user1)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["data"]["updatePerson"] == nil
assert hd(json_response(res, 200)["errors"])["message"] ==
"Actor is not owned by authenticated user"
end
test "update_person/3 should fail to update a not existing identity", context do
user = insert(:user)
insert(:actor, user: user, preferred_username: "riri")
mutation = """
mutation {
updatePerson(
id: "48918",
name: "riri updated",
) {
id,
}
}
"""
res =
context.conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["data"]["updatePerson"] == nil
assert hd(json_response(res, 200)["errors"])["message"] ==
"Actor not found"
end
test "delete_person/3 should fail to update a not owned identity", context do
user1 = insert(:user)
user2 = insert(:user)
%Actor{id: person_id} = insert(:actor, user: user2, preferred_username: "riri")
mutation = """
mutation {
deletePerson(id: "#{person_id}") {
id,
}
}
"""
res =
context.conn
|> auth_conn(user1)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["data"]["deletePerson"] == nil
assert hd(json_response(res, 200)["errors"])["message"] ==
"Actor is not owned by authenticated user"
end
test "delete_person/3 should fail to delete a not existing identity", context do
user = insert(:user)
insert(:actor, user: user, preferred_username: "riri")
mutation = """
mutation {
deletePerson(id: "9798665") {
id,
}
}
"""
res =
context.conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["data"]["deletePerson"] == nil
assert hd(json_response(res, 200)["errors"])["message"] ==
"Actor not found"
end
test "delete_person/3 should fail to delete the last user identity", context do
user = insert(:user)
%Actor{id: person_id} = insert(:actor, user: user, preferred_username: "riri")
mutation = """
mutation {
deletePerson(id: "#{person_id}") {
id,
}
}
"""
res =
context.conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["data"]["deletePerson"] == nil
assert hd(json_response(res, 200)["errors"])["message"] ==
"Cannot remove the last identity of a user"
end
test "delete_person/3 should fail to delete an identity that is the last admin of a group",
context do
group = insert(:group)
classic_user = insert(:user)
classic_actor = insert(:actor, user: classic_user, preferred_username: "classic_user")
admin_user = insert(:user)
admin_actor = insert(:actor, user: admin_user, preferred_username: "last_admin")
insert(:actor, user: admin_user)
insert(:member, %{actor: admin_actor, role: :creator, parent: group})
insert(:member, %{actor: classic_actor, role: :member, parent: group})
mutation = """
mutation {
deletePerson(id: "#{admin_actor.id}") {
id,
}
}
"""
res =
context.conn
|> auth_conn(admin_user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["data"]["deletePerson"] == nil
assert hd(json_response(res, 200)["errors"])["message"] ==
"Cannot remove the last administrator of a group"
end
test "delete_person/3 should delete an actor identity", context do
user = insert(:user)
%Actor{id: person_id} = insert(:actor, user: user, preferred_username: "riri")
insert(:actor, user: user, preferred_username: "fifi")
mutation = """
mutation {
deletePerson(id: "#{person_id}") {
id,
}
}
"""
res =
context.conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert_enqueued(
worker: Workers.Background,
args: %{"actor_id" => person_id, "op" => "delete_actor"}
)
assert %{success: 1, failure: 0} == Oban.drain_queue(:background)
query = """
{
person(id: "#{person_id}") {
id,
}
}
"""
res =
context.conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "person"))
assert hd(json_response(res, 200)["errors"])["message"] ==
"Person with ID #{person_id} not found"
end
end
describe "get_current_person/3" do
test "get_current_person/3 can return the events the person is going to", context do
user = insert(:user)
actor = insert(:actor, user: user)
query = """
{
loggedPerson {
participations {
event {
uuid,
title
}
}
}
}
"""
res =
context.conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "logged_person"))
assert json_response(res, 200)["data"]["loggedPerson"]["participations"] == []
event = insert(:event, %{organizer_actor: actor})
insert(:participant, %{actor: actor, event: event})
res =
context.conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "logged_person"))
assert json_response(res, 200)["data"]["loggedPerson"]["participations"] == [
%{"event" => %{"title" => event.title, "uuid" => event.uuid}}
]
end
test "find_person/3 can return the events an identity is going to if it's the same actor",
context do
user = insert(:user)
actor = insert(:actor, user: user)
insert(:actor, user: user)
actor_from_other_user = insert(:actor)
query = """
{
person(id: "#{actor.id}") {
participations {
event {
uuid,
title
}
}
}
}
"""
res =
context.conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "person"))
assert json_response(res, 200)["data"]["person"]["participations"] == []
query = """
{
person(id: "#{actor_from_other_user.id}") {
participations {
event {
uuid,
title
}
}
}
}
"""
res =
context.conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "person"))
assert json_response(res, 200)["data"]["person"]["participations"] == nil
assert hd(json_response(res, 200)["errors"])["message"] ==
"Actor id is not owned by authenticated user"
end
test "find_person/3 can return the participation for an identity on a specific event",
context do
user = insert(:user)
actor = insert(:actor, user: user)
event = insert(:event, organizer_actor: actor)
insert(:participant, event: event, actor: actor)
query = """
{
person(id: "#{actor.id}") {
participations(eventId: "#{event.id}") {
event {
uuid,
title
}
}
}
}
"""
res =
context.conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "person"))
assert json_response(res, 200)["data"]["person"]["participations"] == [
%{
"event" => %{
"uuid" => event.uuid,
"title" => event.title
}
}
]
end
end
end

View File

@@ -0,0 +1,147 @@
defmodule Mobilizon.GraphQL.Resolvers.PictureTest do
use MobilizonWeb.ConnCase
use Bamboo.Test
import Mobilizon.Factory
alias Mobilizon.Media.Picture
alias Mobilizon.GraphQL.AbsintheHelpers
setup %{conn: conn} do
user = insert(:user)
actor = insert(:actor, user: user)
{:ok, conn: conn, user: user, actor: actor}
end
describe "Resolver: Get picture" do
test "picture/3 returns the information on a picture", context do
%Picture{id: id} = picture = insert(:picture)
query = """
{
picture(id: "#{id}") {
name,
alt,
url,
content_type,
size
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "picture"))
assert json_response(res, 200)["data"]["picture"]["name"] == picture.file.name
assert json_response(res, 200)["data"]["picture"]["content_type"] ==
picture.file.content_type
assert json_response(res, 200)["data"]["picture"]["size"] == 13_120
assert json_response(res, 200)["data"]["picture"]["url"] =~
MobilizonWeb.Endpoint.url()
end
test "picture/3 returns nothing on a non-existent picture", context do
query = """
{
picture(id: "3") {
name,
alt,
url
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "picture"))
assert hd(json_response(res, 200)["errors"])["message"] ==
"Picture with ID 3 was not found"
end
end
describe "Resolver: Upload picture" do
test "upload_picture/3 uploads a new picture", %{conn: conn, user: user, actor: actor} do
picture = %{name: "my pic", alt: "represents something", file: "picture.png"}
mutation = """
mutation { uploadPicture(
name: "#{picture.name}",
alt: "#{picture.alt}",
file: "#{picture.file}",
actor_id: #{actor.id}
) {
url,
name,
content_type,
size
}
}
"""
map = %{
"query" => mutation,
picture.file => %Plug.Upload{
path: "test/fixtures/picture.png",
filename: picture.file
}
}
res =
conn
|> auth_conn(user)
|> put_req_header("content-type", "multipart/form-data")
|> post(
"/api",
map
)
assert json_response(res, 200)["data"]["uploadPicture"]["name"] == picture.name
assert json_response(res, 200)["data"]["uploadPicture"]["content_type"] == "image/png"
assert json_response(res, 200)["data"]["uploadPicture"]["size"] == 10_097
assert json_response(res, 200)["data"]["uploadPicture"]["url"]
end
test "upload_picture/3 forbids uploading if no auth", %{conn: conn, actor: actor} do
picture = %{name: "my pic", alt: "represents something", file: "picture.png"}
mutation = """
mutation { uploadPicture(
name: "#{picture.name}",
alt: "#{picture.alt}",
file: "#{picture.file}",
actor_id: #{actor.id}
) {
url,
name
}
}
"""
map = %{
"query" => mutation,
picture.file => %Plug.Upload{
path: "test/fixtures/picture.png",
filename: picture.file
}
}
res =
conn
|> put_req_header("content-type", "multipart/form-data")
|> post(
"/api",
map
)
assert hd(json_response(res, 200)["errors"])["message"] ==
"You need to login to upload a picture"
end
end
end

View File

@@ -0,0 +1,379 @@
defmodule Mobilizon.GraphQL.Resolvers.ReportTest do
use MobilizonWeb.ConnCase
import Mobilizon.Factory
alias Mobilizon.Actors.Actor
alias Mobilizon.Events.Event
alias Mobilizon.Reports.{Note, Report}
alias Mobilizon.Users.User
alias Mobilizon.GraphQL.AbsintheHelpers
describe "Resolver: Report a content" do
test "create_report/3 creates a report", %{conn: conn} do
%User{} = user_reporter = insert(:user)
%Actor{} = reporter = insert(:actor, user: user_reporter)
%Actor{} = reported = insert(:actor)
%Event{} = event = insert(:event, organizer_actor: reported)
mutation = """
mutation {
createReport(
reporter_id: #{reporter.id},
reported_id: #{reported.id},
event_id: #{event.id},
content: "This is an issue"
) {
content,
reporter {
id
},
event {
id
},
status
}
}
"""
res =
conn
|> auth_conn(user_reporter)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["createReport"]["content"] == "This is an issue"
assert json_response(res, 200)["data"]["createReport"]["status"] == "OPEN"
assert json_response(res, 200)["data"]["createReport"]["event"]["id"] == to_string(event.id)
assert json_response(res, 200)["data"]["createReport"]["reporter"]["id"] ==
to_string(reporter.id)
end
test "create_report/3 without being connected doesn't create any report", %{conn: conn} do
%Actor{} = reported = insert(:actor)
mutation = """
mutation {
createReport(
reported_id: #{reported.id},
reporter_id: 5,
content: "This is an issue"
) {
content
}
}
"""
res =
conn
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] |> hd |> Map.get("message") ==
"You need to be logged-in to create reports"
end
end
describe "Resolver: update a report" do
test "update_report/3 updates the report's status", %{conn: conn} do
%User{} = user_moderator = insert(:user, role: :moderator)
%Actor{} = moderator = insert(:actor, user: user_moderator)
%Report{} = report = insert(:report)
mutation = """
mutation {
updateReportStatus(
report_id: #{report.id},
moderator_id: #{moderator.id},
status: RESOLVED
) {
content,
reporter {
id
},
event {
id
},
status
}
}
"""
res =
conn
|> auth_conn(user_moderator)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["updateReportStatus"]["content"] ==
"This is problematic"
assert json_response(res, 200)["data"]["updateReportStatus"]["status"] == "RESOLVED"
assert json_response(res, 200)["data"]["updateReportStatus"]["reporter"]["id"] ==
to_string(report.reporter.id)
end
test "create_report/3 without being connected doesn't create any report", %{conn: conn} do
%User{} = user_moderator = insert(:user, role: :moderator)
%Actor{} = moderator = insert(:actor, user: user_moderator)
%Report{} = report = insert(:report)
mutation = """
mutation {
updateReportStatus(
report_id: #{report.id},
moderator_id: #{moderator.id},
status: RESOLVED
) {
content
}
}
"""
res =
conn
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] |> hd |> Map.get("message") ==
"You need to be logged-in and a moderator to update a report"
end
end
describe "Resolver: Get list of reports" do
test "get an empty list of reports", %{conn: conn} do
%User{} = user_moderator = insert(:user, role: :moderator)
query = """
{
reports {
id,
reported {
preferredUsername
}
}
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "report"))
assert json_response(res, 200)["errors"] |> hd |> Map.get("message") ==
"You need to be logged-in and a moderator to list reports"
res =
conn
|> auth_conn(user_moderator)
|> get("/api", AbsintheHelpers.query_skeleton(query, "report"))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["reports"] == []
end
test "get a list of reports", %{conn: conn} do
%User{} = user_moderator = insert(:user, role: :moderator)
# Report don't hold millisecond information so we need to wait a bit
# between each insert to keep order
%Report{id: report_1_id} = insert(:report, content: "My content 1")
Process.sleep(1000)
%Report{id: report_2_id} = insert(:report, content: "My content 2")
Process.sleep(1000)
%Report{id: report_3_id} = insert(:report, content: "My content 3")
%Report{} = insert(:report, status: :closed)
query = """
{
reports {
id,
reported {
preferredUsername
},
content,
updatedAt
}
}
"""
res =
conn
|> auth_conn(user_moderator)
|> get("/api", AbsintheHelpers.query_skeleton(query, "report"))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["reports"]
|> Enum.map(fn report -> Map.get(report, "id") end) ==
Enum.map([report_3_id, report_2_id, report_1_id], &to_string/1)
query = """
{
reports(page: 2, limit: 2) {
id,
reported {
preferredUsername
}
}
}
"""
res =
conn
|> auth_conn(user_moderator)
|> get("/api", AbsintheHelpers.query_skeleton(query, "report"))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["reports"] |> length == 1
query = """
{
reports(page: 3, limit: 2) {
id,
reported {
preferredUsername
}
}
}
"""
res =
conn
|> auth_conn(user_moderator)
|> get("/api", AbsintheHelpers.query_skeleton(query, "report"))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["reports"] |> length == 0
end
end
describe "Resolver: View a report" do
test "view a report", %{conn: conn} do
%User{} = user_moderator = insert(:user, role: :moderator)
%Actor{} = insert(:actor, user: user_moderator)
%Actor{} = reporter = insert(:actor)
%Report{} = report = insert(:report, reporter: reporter)
query = """
{
report (id: "#{report.id}") {
id,
reported {
preferredUsername
},
reporter {
preferredUsername
},
event {
title
},
comments {
text
},
content
}
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "report"))
assert json_response(res, 200)["errors"] |> hd |> Map.get("message") ==
"You need to be logged-in and a moderator to view a report"
res =
conn
|> auth_conn(user_moderator)
|> get("/api", AbsintheHelpers.query_skeleton(query, "report"))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["report"]["reported"]["preferredUsername"] ==
report.reported.preferred_username
assert json_response(res, 200)["data"]["report"]["reporter"]["preferredUsername"] ==
reporter.preferred_username
assert json_response(res, 200)["data"]["report"]["content"] == report.content
assert json_response(res, 200)["data"]["report"]["event"]["title"] == report.event.title
assert json_response(res, 200)["data"]["report"]["comments"] |> hd |> Map.get("text") ==
report.comments |> hd |> Map.get(:text)
end
end
describe "Resolver: Add a note on a report" do
@report_note_content "I agree with this this report"
test "create_report_note/3 creates a report note", %{conn: conn} do
%User{} = user_moderator = insert(:user, role: :moderator)
%Actor{id: moderator_id} = moderator = insert(:actor, user: user_moderator)
%Report{id: report_id} = insert(:report)
mutation = """
mutation {
createReportNote(
moderator_id: #{moderator_id},
report_id: #{report_id},
content: "#{@report_note_content}"
) {
content,
moderator {
preferred_username
},
report {
id
}
}
}
"""
res =
conn
|> auth_conn(user_moderator)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["createReportNote"]["content"] ==
@report_note_content
assert json_response(res, 200)["data"]["createReportNote"]["moderator"][
"preferred_username"
] == moderator.preferred_username
assert json_response(res, 200)["data"]["createReportNote"]["report"]["id"] ==
to_string(report_id)
end
test "delete_report_note deletes a report note", %{conn: conn} do
%User{} = user_moderator = insert(:user, role: :moderator)
%Actor{id: moderator_id} = moderator = insert(:actor, user: user_moderator)
%Note{id: report_note_id} = insert(:report_note, moderator: moderator)
mutation = """
mutation {
deleteReportNote(
moderator_id: #{moderator_id},
note_id: #{report_note_id},
) {
id
}
}
"""
res =
conn
|> auth_conn(user_moderator)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["deleteReportNote"]["id"] ==
to_string(report_note_id)
end
end
end

View File

@@ -0,0 +1,261 @@
defmodule Mobilizon.GraphQL.Resolvers.SearchTest do
use MobilizonWeb.ConnCase
import Mobilizon.Factory
alias Mobilizon.Service.Workers
alias Mobilizon.GraphQL.AbsintheHelpers
setup %{conn: conn} do
user = insert(:user)
{:ok, conn: conn, user: user}
end
test "search_events/3 finds events with basic search", %{
conn: conn,
user: user
} do
insert(:actor, user: user, preferred_username: "test_person")
insert(:actor, type: :Group, preferred_username: "test_group")
event = insert(:event, title: "test_event")
Workers.BuildSearch.insert_search_event(event)
query = """
{
search_events(search: "test") {
total,
elements {
title,
uuid,
__typename
}
},
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "search"))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["search_events"]["total"] == 1
assert json_response(res, 200)["data"]["search_events"]["elements"] |> length == 1
assert hd(json_response(res, 200)["data"]["search_events"]["elements"])["uuid"] ==
to_string(event.uuid)
end
test "search_persons/3 finds persons with basic search", %{
conn: conn,
user: user
} do
actor = insert(:actor, user: user, preferred_username: "test_person")
insert(:actor, type: :Group, preferred_username: "test_group")
event = insert(:event, title: "test_event")
Workers.BuildSearch.insert_search_event(event)
query = """
{
search_persons(search: "test") {
total,
elements {
preferredUsername,
__typename
}
},
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "search"))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["search_persons"]["total"] == 1
assert json_response(res, 200)["data"]["search_persons"]["elements"] |> length == 1
assert hd(json_response(res, 200)["data"]["search_persons"]["elements"])["preferredUsername"] ==
actor.preferred_username
end
test "search_groups/3 finds persons with basic search", %{
conn: conn,
user: user
} do
insert(:actor, user: user, preferred_username: "test_person")
group = insert(:actor, type: :Group, preferred_username: "test_group")
event = insert(:event, title: "test_event")
Workers.BuildSearch.insert_search_event(event)
query = """
{
search_groups(search: "test") {
total,
elements {
preferredUsername,
__typename
}
},
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "search"))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["search_groups"]["total"] == 1
assert json_response(res, 200)["data"]["search_groups"]["elements"] |> length == 1
assert hd(json_response(res, 200)["data"]["search_groups"]["elements"])["preferredUsername"] ==
group.preferred_username
end
test "search_events/3 finds events and actors with word search", %{
conn: conn,
user: user
} do
insert(:actor, user: user, preferred_username: "person", name: "I like pineapples")
event1 = insert(:event, title: "Pineapple fashion week")
event2 = insert(:event, title: "I love pineAPPLE")
event3 = insert(:event, title: "Hello")
Workers.BuildSearch.insert_search_event(event1)
Workers.BuildSearch.insert_search_event(event2)
Workers.BuildSearch.insert_search_event(event3)
query = """
{
search_events(search: "pineapple") {
total,
elements {
title,
uuid,
__typename
}
}
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "search"))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["search_events"]["total"] == 2
assert json_response(res, 200)["data"]["search_events"]["elements"]
|> length == 2
assert json_response(res, 200)["data"]["search_events"]["elements"]
|> Enum.map(& &1["title"]) == [
"Pineapple fashion week",
"I love pineAPPLE"
]
end
test "search_persons/3 finds persons with word search", %{
conn: conn,
user: user
} do
actor = insert(:actor, user: user, preferred_username: "person", name: "I like pineapples")
insert(:actor, preferred_username: "group", type: :Group, name: "pineapple group")
event1 = insert(:event, title: "Pineapple fashion week")
event2 = insert(:event, title: "I love pineAPPLE")
event3 = insert(:event, title: "Hello")
Workers.BuildSearch.insert_search_event(event1)
Workers.BuildSearch.insert_search_event(event2)
Workers.BuildSearch.insert_search_event(event3)
query = """
{
search_persons(search: "pineapple") {
total,
elements {
preferredUsername,
__typename
}
}
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "search"))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["search_persons"]["total"] == 1
assert json_response(res, 200)["data"]["search_persons"]["elements"]
|> length == 1
assert hd(json_response(res, 200)["data"]["search_persons"]["elements"])["preferredUsername"] ==
actor.preferred_username
end
test "search_events/3 finds events with accented search", %{
conn: conn,
user: user
} do
insert(:actor, user: user, preferred_username: "person", name: "Torréfaction du Kafé")
insert(:actor, type: :Group, preferred_username: "group", name: "Kafé group")
event = insert(:event, title: "Tour du monde des Kafés")
Workers.BuildSearch.insert_search_event(event)
# Elaborate query
query = """
{
search_events(search: "Kafé") {
total,
elements {
title,
uuid,
__typename
}
}
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "search"))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["search_events"]["total"] == 1
assert hd(json_response(res, 200)["data"]["search_events"]["elements"])["uuid"] == event.uuid
end
test "search_groups/3 finds groups with accented search", %{
conn: conn,
user: user
} do
insert(:actor, user: user, preferred_username: "person", name: "Torréfaction du Kafé")
group = insert(:actor, type: :Group, preferred_username: "group", name: "Kafé group")
event = insert(:event, title: "Tour du monde des Kafés")
Workers.BuildSearch.insert_search_event(event)
# Elaborate query
query = """
{
search_groups(search: "Kafé") {
total,
elements {
preferredUsername,
__typename
}
}
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "search"))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["search_groups"]["total"] == 1
assert hd(json_response(res, 200)["data"]["search_groups"]["elements"])["preferredUsername"] ==
group.preferred_username
end
end

View File

@@ -0,0 +1,49 @@
defmodule Mobilizon.GraphQL.Resolvers.TagTest do
use MobilizonWeb.ConnCase
import Mobilizon.Factory
alias Mobilizon.GraphQL.AbsintheHelpers
describe "Tag Resolver" do
test "list_tags/3 returns the list of tags", context do
tag1 = insert(:tag)
tag2 = insert(:tag)
tag3 = insert(:tag)
insert(:tag_relation, tag: tag1, link: tag2)
insert(:tag_relation, tag: tag3, link: tag1)
query = """
{
tags {
id,
slug,
title,
related {
id,
title,
slug
}
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "tags"))
tags = json_response(res, 200)["data"]["tags"]
assert tags |> length == 3
assert tags
|> Enum.filter(fn tag -> tag["slug"] == tag1.slug end)
|> hd
|> Map.get("related")
|> Enum.map(fn tag -> tag["slug"] end)
|> MapSet.new() ==
[tag2, tag3]
|> Enum.map(fn tag -> tag.slug end)
|> MapSet.new()
end
end
end

File diff suppressed because it is too large Load Diff