mobilizon/test/graphql/resolvers/event_test.exs

1457 lines
39 KiB
Elixir

defmodule Mobilizon.Web.Resolvers.EventTest do
use Mobilizon.Web.ConnCase
use Bamboo.Test
use Oban.Testing, repo: Mobilizon.Storage.Repo
import Mobilizon.Factory
alias Mobilizon.Events
alias Mobilizon.Service.Workers
alias Mobilizon.GraphQL.AbsintheHelpers
alias Mobilizon.Web.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"
}
setup %{conn: conn} do
user = insert(:user)
actor = insert(:actor, user: user, preferred_username: "test")
{:ok, conn: conn, actor: actor, user: user}
end
describe "Event Resolver" do
@find_event_query """
query Event($uuid: UUID!) {
event(uuid: $uuid) {
uuid,
draft
}
}
"""
test "find_event/3 returns an event", context do
event =
@event
|> Map.put(:organizer_actor_id, context.actor.id)
{:ok, event} = Events.create_event(event)
res =
context.conn
|> AbsintheHelpers.graphql_query(query: @find_event_query, variables: %{uuid: event.uuid})
assert res["data"]["event"]["uuid"] == to_string(event.uuid)
res =
context.conn
|> AbsintheHelpers.graphql_query(query: @find_event_query, variables: %{uuid: "bad uuid"})
assert [%{"message" => "Argument \"uuid\" has invalid value $uuid."}] = res["errors"]
res =
context.conn
|> AbsintheHelpers.graphql_query(
query: @find_event_query,
variables: %{uuid: "b5126423-f1af-43e4-a923-002a03003ba5"}
)
assert [%{"message" => "Event with UUID b5126423-f1af-43e4-a923-002a03003ba5 not found"}] =
res["errors"]
end
@create_event_mutation """
mutation CreateEvent(
$title: String!,
$description: String,
$begins_on: DateTime!,
$ends_on: DateTime,
$status: EventStatus,
$visibility: EventVisibility,
$organizer_actor_id: ID!,
$online_address: String,
$options: EventOptionsInput,
$draft: Boolean
) {
createEvent(
title: $title,
description: $description,
begins_on: $begins_on,
ends_on: $ends_on,
status: $status,
visibility: $visibility,
organizer_actor_id: $organizer_actor_id,
online_address: $online_address,
options: $options,
draft: $draft
) {
id,
uuid,
title,
description,
begins_on,
ends_on,
status,
visibility,
organizer_actor {
id
},
online_address,
phone_address,
category,
draft,
options {
maximumAttendeeCapacity,
showRemainingAttendeeCapacity,
showEndTime
}
}
}
"""
test "create_event/3 should check the organizer_actor_id is owned by the user", %{
conn: conn,
user: user
} do
another_actor = insert(:actor)
begins_on = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601()
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @create_event_mutation,
variables: %{
title: "come to my event",
description: "it will be fine",
begins_on: "#{begins_on}",
organizer_actor_id: "#{another_actor.id}"
}
)
assert res["data"]["createEvent"] == nil
assert hd(res["errors"])["message"] ==
"Organizer actor id is not owned by the user"
end
test "create_event/3 should check that end time is after start time", %{
conn: conn,
actor: actor,
user: user
} do
begins_on = DateTime.utc_now() |> DateTime.truncate(:second)
ends_on = DateTime.add(begins_on, -2 * 3600)
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @create_event_mutation,
variables: %{
title: "come to my event",
description: "it will be fine",
begins_on: "#{begins_on}",
ends_on: "#{ends_on}",
organizer_actor_id: "#{actor.id}"
}
)
assert hd(res["errors"])["message"] ==
"ends_on cannot be set before begins_on"
end
test "create_event/3 creates an event", %{conn: conn, actor: actor, user: user} do
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @create_event_mutation,
variables: %{
title: "come to my event",
description: "it will be fine",
begins_on: "#{DateTime.utc_now()}",
organizer_actor_id: "#{actor.id}"
}
)
assert res["data"]["createEvent"]["title"] == "come to my event"
{id, ""} = res["data"]["createEvent"]["id"] |> Integer.parse()
assert_enqueued(
worker: Workers.BuildSearch,
args: %{event_id: id, op: :insert_search_event}
)
end
test "create_event/3 creates an event and escapes title and description", %{
conn: conn,
actor: actor,
user: user
} do
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @create_event_mutation,
variables: %{
title:
"My Event title <img src=\"http://placekitten.com/g/200/300\" onclick=\"alert('aaa')\" >",
description:
"<b>My description</b> <img src=\"http://placekitten.com/g/200/300\" onclick=\"alert('aaa')\" >",
begins_on: DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601(),
organizer_actor_id: "#{actor.id}"
}
)
assert res["errors"] == nil
assert res["data"]["createEvent"]["title"] == "My Event title"
assert res["data"]["createEvent"]["description"] ==
"<b>My description</b> <img src=\"http://placekitten.com/g/200/300\"/>"
{id, ""} = res["data"]["createEvent"]["id"] |> Integer.parse()
assert_enqueued(
worker: Workers.BuildSearch,
args: %{event_id: id, op: :insert_search_event}
)
end
test "create_event/3 creates an event as a draft", %{conn: conn, actor: actor, user: user} do
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @create_event_mutation,
variables: %{
title: "come to my event",
description: "it will be fine",
begins_on: "#{DateTime.utc_now()}",
organizer_actor_id: "#{actor.id}",
draft: true
}
)
assert res["data"]["createEvent"]["title"] == "come to my event"
assert res["data"]["createEvent"]["draft"] == true
event_uuid = res["data"]["createEvent"]["uuid"]
event_id = res["data"]["createEvent"]["id"]
{event_id_int, ""} = Integer.parse(event_id)
refute_enqueued(
worker: Workers.BuildSearch,
args: %{event_id: event_id_int, op: :insert_search_event}
)
res =
conn
|> AbsintheHelpers.graphql_query(query: @find_event_query, variables: %{uuid: event_uuid})
assert hd(res["errors"])["message"] =~ "not found"
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(query: @find_event_query, variables: %{uuid: event_uuid})
assert res["errors"] == nil
assert res["data"]["event"]["draft"] == true
query = """
query Person($actor_id: ID!, $event_id: ID) {
person(id: $actor_id) {
id,
participations(eventId: $event_id) {
elements {
id,
role,
actor {
id
},
event {
id
}
}
}
}
}
"""
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: query,
variables: %{actor_id: actor.id, event_id: event_id}
)
assert res["errors"] == nil
assert res["data"]["person"]["participations"]["elements"] == []
end
test "create_event/3 creates an event with options", %{conn: conn, actor: actor, user: user} do
begins_on = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601()
ends_on = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601()
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @create_event_mutation,
variables: %{
title: "come to my event",
description: "it will be fine",
begins_on: "#{begins_on}",
ends_on: "#{ends_on}",
status: "TENTATIVE",
visibility: "UNLISTED",
organizer_actor_id: "#{actor.id}",
online_address: "toto@example.com",
options: %{
maximumAttendeeCapacity: 30,
showRemainingAttendeeCapacity: true,
showEndTime: false
}
}
)
assert res["errors"] == nil
event = res["data"]["createEvent"]
assert event["title"] == "come to my event"
assert event["description"] == "it will be fine"
assert event["begins_on"] == begins_on
assert event["ends_on"] == ends_on
assert event["status"] == "TENTATIVE"
assert event["visibility"] == "UNLISTED"
assert event["organizer_actor"]["id"] == "#{actor.id}"
assert event["online_address"] == "toto@example.com"
assert event["options"]["maximumAttendeeCapacity"] == 30
assert event["options"]["showRemainingAttendeeCapacity"] == true
assert event["options"]["showEndTime"] == false
{event_id_int, ""} = Integer.parse(event["id"])
assert_enqueued(
worker: Workers.BuildSearch,
args: %{event_id: event_id_int, op: :insert_search_event}
)
end
test "create_event/3 creates an event an invalid options", %{
conn: conn,
actor: actor,
user: user
} do
begins_on = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601()
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @create_event_mutation,
variables: %{
title: "come to my event",
description: "it will be fine",
begins_on: "#{begins_on}",
organizer_actor_id: "#{actor.id}",
options: %{
maximumAttendeeCapacity: -5
}
}
)
assert hd(res["errors"])["message"] == "must be greater than or equal to %{number}"
end
test "create_event/3 creates an event with tags", %{conn: conn, actor: actor, user: user} do
mutation = """
mutation {
createEvent(
title: "my event is referenced",
description: "with tags!",
begins_on: "#{
DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601()
}",
organizer_actor_id: "#{actor.id}",
category: "birthday",
tags: ["nicolas", "birthday", "bad tag"]
) {
title,
uuid,
tags {
title,
slug
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["createEvent"]["title"] == "my event is referenced"
assert json_response(res, 200)["data"]["createEvent"]["tags"] == [
%{"slug" => "nicolas", "title" => "nicolas"},
%{"slug" => "birthday", "title" => "birthday"},
%{"slug" => "bad-tag", "title" => "bad tag"}
]
end
test "create_event/3 creates an event with an address", %{
conn: conn,
actor: actor,
user: user
} do
address = %{street: "I am a street, please believe me", locality: "Where ever"}
mutation = """
mutation {
createEvent(
title: "my event is referenced",
description: "with tags!",
begins_on: "#{
DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601()
}",
organizer_actor_id: "#{actor.id}",
category: "birthday",
physical_address: {
street: "#{address.street}",
locality: "#{address.locality}"
}
) {
title,
uuid,
physicalAddress {
id,
url,
geom,
street
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["createEvent"]["title"] == "my event is referenced"
assert json_response(res, 200)["data"]["createEvent"]["physicalAddress"]["street"] ==
address.street
address_url = json_response(res, 200)["data"]["createEvent"]["physicalAddress"]["url"]
address_id = json_response(res, 200)["data"]["createEvent"]["physicalAddress"]["id"]
mutation = """
mutation {
createEvent(
title: "my event is referenced",
description: "with tags!",
begins_on: "#{
DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601()
}",
organizer_actor_id: "#{actor.id}",
category: "birthday",
physical_address: {
id: "#{address_id}"
}
) {
title,
uuid,
physicalAddress {
id,
url,
geom,
street
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["createEvent"]["title"] == "my event is referenced"
assert json_response(res, 200)["data"]["createEvent"]["physicalAddress"]["street"] ==
address.street
assert json_response(res, 200)["data"]["createEvent"]["physicalAddress"]["id"] ==
address_id
assert json_response(res, 200)["data"]["createEvent"]["physicalAddress"]["url"] ==
address_url
end
test "create_event/3 creates an event with an attached picture", %{
conn: conn,
actor: actor,
user: user
} do
mutation = """
mutation {
createEvent(
title: "come to my event",
description: "it will be fine",
begins_on: "#{
DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601()
}",
organizer_actor_id: "#{actor.id}",
category: "birthday",
picture: {
picture: {
name: "picture for my event",
alt: "A very sunny landscape",
file: "event.jpg",
actor_id: #{actor.id}
}
}
) {
title,
uuid,
picture {
name,
url
}
}
}
"""
map = %{
"query" => mutation,
"event.jpg" => %Plug.Upload{
path: "test/fixtures/picture.png",
filename: "event.jpg"
}
}
res =
conn
|> auth_conn(user)
|> put_req_header("content-type", "multipart/form-data")
|> post("/api", map)
assert json_response(res, 200)["data"]["createEvent"]["title"] == "come to my event"
assert json_response(res, 200)["data"]["createEvent"]["picture"]["name"] ==
"picture for my event"
end
test "create_event/3 creates an event with an picture ID", %{
conn: conn,
actor: actor,
user: user
} 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}
) {
id,
url,
name
}
}
"""
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
picture_id = json_response(res, 200)["data"]["uploadPicture"]["id"]
mutation = """
mutation {
createEvent(
title: "come to my event",
description: "it will be fine",
begins_on: "#{
DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601()
}",
organizer_actor_id: "#{actor.id}",
category: "birthday",
picture: {
picture_id: "#{picture_id}"
}
) {
title,
uuid,
picture {
name,
url
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["data"]["createEvent"]["title"] == "come to my event"
assert json_response(res, 200)["data"]["createEvent"]["picture"]["name"] == picture.name
assert json_response(res, 200)["data"]["createEvent"]["picture"]["url"]
end
test "update_event/3 should check the event exists", %{conn: conn, actor: _actor, user: user} do
mutation = """
mutation {
updateEvent(
event_id: 45,
title: "my event updated"
) {
title,
uuid,
tags {
title,
slug
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] == "Event not found"
end
test "update_event/3 should check the user is an administrator", %{
conn: conn,
actor: _actor,
user: user
} do
event = insert(:event)
mutation = """
mutation {
updateEvent(
title: "my event updated",
event_id: #{event.id}
) {
title,
uuid,
tags {
title,
slug
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] == "User doesn't own actor"
end
test "update_event/3 should check end time is after the beginning time", %{
conn: conn,
actor: actor,
user: user
} do
event = insert(:event, organizer_actor: actor)
mutation = """
mutation {
updateEvent(
title: "my event updated",
ends_on: "#{Timex.shift(event.begins_on, hours: -2)}",
event_id: #{event.id}
) {
title,
uuid,
tags {
title,
slug
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] ==
"ends_on cannot be set before begins_on"
end
test "update_event/3 updates an event", %{conn: conn, actor: actor, user: user} do
event = insert(:event, organizer_actor: actor)
_creator = insert(:participant, event: event, actor: actor, role: :creator)
participant_user = insert(:user)
participant_actor = insert(:actor, user: participant_user)
_participant =
insert(:participant, event: event, actor: participant_actor, role: :participant)
address = insert(:address)
begins_on = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601()
ends_on = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601()
mutation = """
mutation {
updateEvent(
event_id: #{event.id},
title: "my event updated",
description: "description updated",
begins_on: "#{begins_on}",
ends_on: "#{ends_on}",
status: TENTATIVE,
tags: ["tag1_updated", "tag2_updated"],
online_address: "toto@example.com",
phone_address: "0000000000",
category: "birthday",
options: {
maximumAttendeeCapacity: 30,
showRemainingAttendeeCapacity: true
},
physical_address: {
street: "#{address.street}",
locality: "#{address.locality}"
}
) {
id,
uuid,
url,
title,
description,
begins_on,
ends_on,
status,
tags {
title,
slug
},
online_address,
phone_address,
category,
options {
maximumAttendeeCapacity,
showRemainingAttendeeCapacity
},
physicalAddress {
url,
geom,
street
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
event_res = json_response(res, 200)["data"]["updateEvent"]
assert event_res["title"] == "my event updated"
assert event_res["description"] == "description updated"
assert event_res["begins_on"] == "#{begins_on}"
assert event_res["ends_on"] == "#{ends_on}"
assert event_res["status"] == "TENTATIVE"
assert event_res["online_address"] == "toto@example.com"
assert event_res["phone_address"] == "0000000000"
assert event_res["category"] == "birthday"
assert event_res["options"]["maximumAttendeeCapacity"] == 30
assert event_res["options"]["showRemainingAttendeeCapacity"] == true
assert event_res["uuid"] == event.uuid
assert event_res["url"] == event.url
assert event_res["physicalAddress"]["street"] == address.street
refute event_res["physicalAddress"]["url"] == address.url
assert event_res["tags"] == [
%{"slug" => "tag1-updated", "title" => "tag1_updated"},
%{"slug" => "tag2-updated", "title" => "tag2_updated"}
]
{event_id_int, ""} = Integer.parse(event_res["id"])
assert_enqueued(
worker: Workers.BuildSearch,
args: %{event_id: event_id_int, op: :update_search_event}
)
{:ok, new_event} = Mobilizon.Events.get_event_with_preload(event.id)
assert_delivered_email(
Email.Event.event_updated(
user,
actor,
event,
new_event,
MapSet.new([:title, :begins_on, :ends_on, :status, :physical_address])
)
)
assert_delivered_email(
Email.Event.event_updated(
participant_user,
participant_actor,
event,
new_event,
MapSet.new([:title, :begins_on, :ends_on, :status, :physical_address])
)
)
end
test "update_event/3 updates an event with a new picture", %{
conn: conn,
actor: actor,
user: user
} do
event = insert(:event, organizer_actor: actor)
begins_on =
event.begins_on
|> Timex.shift(hours: 3)
|> DateTime.truncate(:second)
|> DateTime.to_iso8601()
mutation = """
mutation {
updateEvent(
title: "my event updated",
description: "description updated",
begins_on: "#{begins_on}",
event_id: #{event.id},
category: "birthday",
picture: {
picture: {
name: "picture for my event",
alt: "A very sunny landscape",
file: "event.jpg",
actor_id: "#{actor.id}"
}
}
) {
title,
uuid,
url,
beginsOn,
picture {
name,
url
}
}
}
"""
map = %{
"query" => mutation,
"event.jpg" => %Plug.Upload{
path: "test/fixtures/picture.png",
filename: "event.jpg"
}
}
res =
conn
|> auth_conn(user)
|> put_req_header("content-type", "multipart/form-data")
|> post("/api", map)
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["updateEvent"]["title"] == "my event updated"
assert json_response(res, 200)["data"]["updateEvent"]["uuid"] == event.uuid
assert json_response(res, 200)["data"]["updateEvent"]["url"] == event.url
assert json_response(res, 200)["data"]["updateEvent"]["beginsOn"] ==
DateTime.to_iso8601(event.begins_on |> Timex.shift(hours: 3))
assert json_response(res, 200)["data"]["updateEvent"]["picture"]["name"] ==
"picture for my event"
end
test "update_event/3 respects the draft status", %{conn: conn, actor: actor, user: user} do
event = insert(:event, organizer_actor: actor, draft: true)
mutation = """
mutation {
updateEvent(
event_id: #{event.id},
title: "my event updated but still draft"
) {
draft,
title,
uuid
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["data"]["updateEvent"]["draft"] == true
query = """
{
event(uuid: "#{event.uuid}") {
uuid,
draft
}
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
assert hd(json_response(res, 200)["errors"])["message"] =~ "not found"
query = """
{
event(uuid: "#{event.uuid}") {
uuid,
draft
}
}
"""
res =
conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["event"]["draft"] == true
query = """
{
person(id: "#{actor.id}") {
id,
participations(eventId: #{event.id}) {
elements {
id,
role,
actor {
id
},
event {
id
}
}
}
}
}
"""
res =
conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "person"))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["person"]["participations"]["elements"] == []
mutation = """
mutation {
updateEvent(
event_id: #{event.id},
title: "my event updated and no longer draft",
draft: false
) {
draft,
title,
uuid
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["data"]["updateEvent"]["draft"] == false
query = """
{
event(uuid: "#{event.uuid}") {
uuid,
draft
}
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["event"]["draft"] == false
query = """
{
person(id: "#{actor.id}") {
id,
participations(eventId: #{event.id}) {
elements {
role,
actor {
id
},
event {
id
}
}
}
}
}
"""
res =
conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "person"))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["person"]["participations"]["elements"] == [
%{
"actor" => %{"id" => to_string(actor.id)},
"event" => %{"id" => to_string(event.id)},
"role" => "CREATOR"
}
]
end
test "list_events/3 returns events", context do
event = insert(:event)
query = """
{
events {
uuid,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
assert json_response(res, 200)["data"]["events"] |> Enum.map(& &1["uuid"]) == [event.uuid]
Enum.each(0..15, fn _ ->
insert(:event)
end)
query = """
{
events {
uuid,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
assert json_response(res, 200)["data"]["events"] |> length == 10
query = """
{
events(page: 2) {
uuid,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
assert json_response(res, 200)["data"]["events"] |> length == 7
query = """
{
events(page: 2, limit: 15) {
uuid,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
assert json_response(res, 200)["data"]["events"] |> length == 2
query = """
{
events(page: 3, limit: 15) {
uuid,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
assert json_response(res, 200)["data"]["events"] |> length == 0
end
test "list_events/3 doesn't list private events", context do
insert(:event, visibility: :private)
insert(:event, visibility: :unlisted)
insert(:event, visibility: :restricted)
query = """
{
events {
uuid,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
assert json_response(res, 200)["data"]["events"] |> Enum.map(& &1["uuid"]) == []
end
test "list_events/3 doesn't list draft events", context do
insert(:event, visibility: :public, draft: true)
query = """
{
events {
uuid,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
assert json_response(res, 200)["data"]["events"] |> Enum.map(& &1["uuid"]) == []
end
test "find_event/3 returns an unlisted event", context do
event = insert(:event, visibility: :unlisted)
query = """
{
event(uuid: "#{event.uuid}") {
uuid,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
assert json_response(res, 200)["data"]["event"]["uuid"] == to_string(event.uuid)
end
# test "find_event/3 doesn't return a private event", context do
# event = insert(:event, visibility: :private)
#
# query = """
# {
# event(uuid: "#{event.uuid}") {
# uuid,
# }
# }
# """
#
# res =
# context.conn
# |> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
#
# assert json_response(res, 200)["errors"] |> hd |> Map.get("message") ==
# "Event with UUID #{event.uuid} not found"
# end
test "delete_event/3 deletes an event", %{conn: conn, user: user, actor: actor} do
event = insert(:event, organizer_actor: actor)
mutation = """
mutation {
deleteEvent(
actor_id: #{actor.id},
event_id: #{event.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"]["deleteEvent"]["id"] == to_string(event.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_event/3 should check the user is authenticated", %{conn: conn, actor: actor} do
event = insert(:event, organizer_actor: actor)
mutation = """
mutation {
deleteEvent(
actor_id: #{actor.id},
event_id: #{event.id}
) {
id
}
}
"""
res =
conn
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "logged-in"
end
test "delete_event/3 should check the actor id is owned by the user", %{
conn: conn,
user: user,
actor: actor
} do
event = insert(:event, organizer_actor: actor)
mutation = """
mutation {
deleteEvent(
actor_id: 1042,
event_id: #{event.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_event/3 should check the event can be deleted by the user", %{
conn: conn,
user: user,
actor: actor
} do
actor2 = insert(:actor)
event = insert(:event, organizer_actor: actor2)
mutation = """
mutation {
deleteEvent(
actor_id: #{actor.id},
event_id: #{event.id}
) {
id
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "cannot delete"
end
test "delete_event/3 allows a event 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)
event = insert(:event, organizer_actor: actor2)
mutation = """
mutation {
deleteEvent(
actor_id: #{actor_moderator.id},
event_id: #{event.id}
) {
id
}
}
"""
res =
conn
|> auth_conn(user_moderator)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["data"]["deleteEvent"]["id"] == to_string(event.id)
query = """
{
actionLogs {
action,
actor {
preferredUsername
},
object {
... on Report {
id,
status
},
... on ReportNote {
content
}
... on Event {
id,
title
}
}
}
}
"""
res =
conn
|> auth_conn(user_moderator)
|> get("/api", AbsintheHelpers.query_skeleton(query, "actionLogs"))
assert hd(json_response(res, 200)["data"]["actionLogs"]) == %{
"action" => "EVENT_DELETION",
"actor" => %{"preferredUsername" => actor_moderator.preferred_username},
"object" => %{"title" => event.title, "id" => to_string(event.id)}
}
end
test "list_related_events/3 should give related events", %{
conn: conn,
actor: actor
} do
tag1 = insert(:tag, title: "Elixir", slug: "elixir")
tag2 = insert(:tag, title: "PostgreSQL", slug: "postgresql")
event = insert(:event, title: "Initial event", organizer_actor: actor, tags: [tag1, tag2])
event2 =
insert(:event,
title: "Event from same actor",
organizer_actor: actor,
visibility: :public,
begins_on: Timex.shift(DateTime.utc_now(), days: 3)
)
event3 =
insert(:event,
title: "Event with same tags",
tags: [tag1, tag2],
visibility: :public,
begins_on: Timex.shift(DateTime.utc_now(), days: 3)
)
query = """
{
event(uuid: "#{event.uuid}") {
uuid,
title,
tags {
id
},
related_events {
uuid,
title,
tags {
id
}
}
}
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
assert hd(json_response(res, 200)["data"]["event"]["related_events"])["uuid"] == event2.uuid
assert hd(tl(json_response(res, 200)["data"]["event"]["related_events"]))["uuid"] ==
event3.uuid
end
end
end