Move to GraphQL

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel
2018-11-06 10:30:27 +01:00
parent 7e137d1a1c
commit b54dae7e15
149 changed files with 5605 additions and 4665 deletions

View File

@@ -0,0 +1,175 @@
defmodule MobilizonWeb.ActivityPubControllerTest do
use MobilizonWeb.ConnCase
import Mobilizon.Factory
alias MobilizonWeb.ActivityPub.{ActorView, ObjectView}
alias Mobilizon.{Repo, Actors, Actors.Actor}
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Activity
import Logger
describe "/@:preferred_username" do
test "it returns a json representation of the actor", %{conn: conn} do
actor = insert(:actor)
conn =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/@#{actor.preferred_username}")
actor = Actors.get_actor!(actor.id)
assert json_response(conn, 200) == ActorView.render("actor.json", %{actor: actor})
Logger.error(inspect(ActorView.render("actor.json", %{actor: actor})))
end
end
describe "/events/:uuid" do
test "it returns a json representation of the event", %{conn: conn} do
event = insert(:event)
conn =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/events/#{event.uuid}")
assert json_response(conn, 200) == ObjectView.render("event.json", %{event: event})
Logger.error(inspect(ObjectView.render("event.json", %{event: event})))
end
test "it returns 404 for non-public events", %{conn: conn} do
event = insert(:event, public: false)
conn =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/events/#{event.uuid}")
assert json_response(conn, 404)
end
end
describe "/@:preferred_username/inbox" do
test "it inserts an incoming event into the database", %{conn: conn} do
data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
conn =
conn
|> assign(:valid_signature, true)
|> put_req_header("content-type", "application/activity+json")
|> post("/inbox", data)
assert "ok" == json_response(conn, 200)
:timer.sleep(500)
assert ActivityPub.fetch_object_from_url(data["object"]["id"], :note)
end
end
describe "/@:preferred_username/outbox" do
test "it returns a note activity in a collection", %{conn: conn} do
actor = insert(:actor)
comment = insert(:comment, actor: actor)
conn =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/@#{actor.preferred_username}/outbox")
assert response(conn, 200) =~ comment.text
end
test "it returns an event activity in a collection", %{conn: conn} do
actor = insert(:actor)
event = insert(:event, organizer_actor: actor)
conn =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/@#{actor.preferred_username}/outbox")
assert response(conn, 200) =~ event.title
end
end
# describe "/actors/:nickname/followers" do
# test "it returns the followers in a collection", %{conn: conn} do
# user = insert(:user)
# user_two = insert(:user)
# User.follow(user, user_two)
#
# result =
# conn
# |> get("/users/#{user_two.nickname}/followers")
# |> json_response(200)
#
# assert result["first"]["orderedItems"] == [user.ap_id]
# end
#
# test "it works for more than 10 users", %{conn: conn} do
# user = insert(:user)
#
# Enum.each(1..15, fn _ ->
# other_user = insert(:user)
# User.follow(other_user, user)
# end)
#
# result =
# conn
# |> get("/users/#{user.nickname}/followers")
# |> json_response(200)
#
# assert length(result["first"]["orderedItems"]) == 10
# assert result["first"]["totalItems"] == 15
# assert result["totalItems"] == 15
#
# result =
# conn
# |> get("/users/#{user.nickname}/followers?page=2")
# |> json_response(200)
#
# assert length(result["orderedItems"]) == 5
# assert result["totalItems"] == 15
# end
# end
#
# describe "/@:preferred_username/following" do
# test "it returns the following in a collection", %{conn: conn} do
# actor = insert(:actor)
# actor2 = insert(:actor)
# Mobilizon.Service.ActivityPub.follow(actor, actor2)
# result =
# conn
# |> get("/@#{actor.preferred_username}/following")
# |> json_response(200)
# assert result["first"]["orderedItems"] == [actor2.url]
# end
# test "it works for more than 10 actors", %{conn: conn} do
# actor = insert(:actor)
# Enum.each(1..15, fn _ ->
# actor = Repo.get(Actor, actor.id)
# other_actor = insert(:actor)
# Actor.follow(actor, other_actor)
# end)
# result =
# conn
# |> get("/@#{actor.preferred_username}/following")
# |> json_response(200)
# assert length(result["first"]["orderedItems"]) == 10
# assert result["first"]["totalItems"] == 15
# assert result["totalItems"] == 15
# result =
# conn
# |> get("/@#{actor.preferred_username}/following?page=2")
# |> json_response(200)
# assert length(result["orderedItems"]) == 5
# assert result["totalItems"] == 15
# end
# end
end

View File

@@ -0,0 +1,38 @@
defmodule MobilizonWeb.NodeInfoControllerTest do
use MobilizonWeb.ConnCase
@instance Application.get_env(:mobilizon, :instance)
test "Get node info schemas", %{conn: conn} do
conn = get(conn, node_info_path(conn, :schemas))
assert json_response(conn, 200) == %{
"links" => [
%{
"href" =>
MobilizonWeb.Router.Helpers.node_info_url(
MobilizonWeb.Endpoint,
:nodeinfo,
"2.0"
),
"rel" => "http://nodeinfo.diaspora.software/ns/schema/2.0"
}
]
}
end
test "Get node info", %{conn: conn} do
conn = get(conn, node_info_path(conn, :nodeinfo, "2.0"))
resp = json_response(conn, 200)
assert resp = %{
"metadata" => %{"nodeName" => Keyword.get(@instance, :name)},
"openRegistrations" => Keyword.get(@instance, :registrations_open),
"protocols" => ["activitypub"],
"services" => %{"inbound" => [], "outbound" => []},
"software" => %{"name" => "mobilizon", "version" => Keyword.get(@instance, :version)},
"version" => "2.0"
}
end
end

View File

@@ -0,0 +1,8 @@
defmodule MobilizonWeb.PageControllerTest do
use MobilizonWeb.ConnCase
test "GET /", %{conn: conn} do
conn = get(conn, "/")
assert html_response(conn, 200)
end
end

View File

@@ -0,0 +1,78 @@
defmodule MobilizonWeb.Resolvers.ActorResolverTest do
use MobilizonWeb.ConnCase
alias Mobilizon.{Events, Actors}
alias Mobilizon.Actors.Actor
alias MobilizonWeb.AbsintheHelpers
import Mobilizon.Factory
@valid_actor_params %{email: "test@test.tld", password: "testest", username: "test"}
@non_existent_username "nonexistent"
describe "Actor Resolver" do
test "find_actor/3 returns an actor by it's username", context do
{:ok, actor} = Actors.register(@valid_actor_params)
query = """
{
actor(preferredUsername: "#{actor.preferred_username}") {
preferredUsername,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "actor"))
assert json_response(res, 200)["data"]["actor"]["preferredUsername"] ==
actor.preferred_username
query = """
{
actor(preferredUsername: "#{@non_existent_username}") {
preferredUsername,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "actor"))
assert json_response(res, 200)["data"]["actor"] == nil
assert hd(json_response(res, 200)["errors"])["message"] ==
"Actor with name #{@non_existent_username} not found"
end
test "get_current_actor/3 returns the current logged-in actor", context do
{:ok, actor} = Actors.register(@valid_actor_params)
query = """
{
loggedActor {
avatarUrl,
preferredUsername,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "logged_actor"))
assert json_response(res, 200)["data"]["loggedActor"] == nil
assert hd(json_response(res, 200)["errors"])["message"] ==
"You need to be logged-in to view current actor"
res =
context.conn
|> auth_conn(actor.user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "logged_actor"))
assert json_response(res, 200)["data"]["loggedActor"]["preferredUsername"] ==
actor.preferred_username
end
end
end

View File

@@ -0,0 +1,60 @@
defmodule MobilizonWeb.Resolvers.CategoryResolverTest do
use MobilizonWeb.ConnCase
alias Mobilizon.Actors
alias Mobilizon.Actors.Actor
alias MobilizonWeb.AbsintheHelpers
import Mobilizon.Factory
setup %{conn: conn} do
{:ok, %Actor{} = actor} =
Actors.register(%{email: "test@test.tld", password: "testest", username: "test"})
{:ok, conn: conn, actor: actor}
end
describe "Category Resolver" do
test "list_categories/3 returns the list of categories", context do
insert(:category)
insert(:category)
query = """
{
categories {
id,
title,
description,
picture {
url,
},
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "categories"))
assert json_response(res, 200)["data"]["categories"] |> length == 2
end
# We can't test an upload…yet?
# test "create_category/3 creates a category", %{conn: conn, actor: actor} do
# mutation = """
# mutation {
# createCategory(title: "my category", description: "my desc") {
# id,
# title,
# description,
# },
# }
# """
# res =
# conn
# |> auth_conn(actor.user)
# |> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
# assert json_response(res, 200)["data"]["createCategory"]["title"] == "my category"
# end
end
end

View File

@@ -0,0 +1,167 @@
defmodule MobilizonWeb.Resolvers.EventResolverTest do
use MobilizonWeb.ConnCase
alias Mobilizon.{Events, Actors}
alias Mobilizon.Actors.Actor
alias MobilizonWeb.AbsintheHelpers
import Mobilizon.Factory
@event %{description: "some body", title: "some title", begins_on: Ecto.DateTime.utc()}
setup %{conn: conn} do
{:ok, %Actor{} = actor} =
Actors.register(%{email: "test@test.tld", password: "testest", username: "test"})
{:ok, conn: conn, actor: actor}
end
describe "Event Resolver" do
test "find_event/3 returns an event", context do
category = insert(:category)
event =
@event
|> Map.put(:organizer_actor_id, context.actor.id)
|> Map.put(:category_id, category.id)
{:ok, event} = Events.create_event(event)
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)
query = """
{
event(uuid: "bad uuid") {
uuid,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
assert [%{"message" => "Argument \"uuid\" has invalid value \"bad uuid\"."}] =
json_response(res, 400)["errors"]
end
test "list_participants_for_event/3 returns participants for an event", context do
# Plain event
category = insert(:category)
event =
@event
|> Map.put(:organizer_actor_id, context.actor.id)
|> Map.put(:category_id, category.id)
{:ok, event} = Events.create_event(event)
query = """
{
participants(uuid: "#{event.uuid}") {
role,
actor {
preferredUsername
}
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "participants"))
assert json_response(res, 200)["data"]["participants"] == [
%{
"actor" => %{"preferredUsername" => context.actor.preferred_username},
"role" => 4
}
]
# Adding a participant
actor2 = insert(:actor)
participant = insert(:participant, event: event, actor: actor2)
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "participants"))
assert json_response(res, 200)["data"]["participants"] == [
%{
"actor" => %{"preferredUsername" => context.actor.preferred_username},
"role" => 4
},
%{
"actor" => %{"preferredUsername" => participant.actor.preferred_username},
"role" => 0
}
]
end
test "create_event/3 creates an event", %{conn: conn, actor: actor} do
category = insert(:category)
mutation = """
mutation {
createEvent(
title: "come to my event",
description: "it will be fine",
beginsOn: "#{DateTime.utc_now() |> DateTime.to_iso8601()}",
organizer_actor_id: #{actor.id},
category_id: #{category.id},
addressType: #{"OTHER"}
) {
title,
uuid
}
}
"""
res =
conn
|> auth_conn(actor.user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["data"]["createEvent"]["title"] == "come to my event"
end
test "search_events_and_actors/3 finds events and actors", %{conn: conn, actor: actor} do
event = insert(:event, title: "test")
query = """
{
search(search: "test") {
...on Event {
title,
uuid,
__typename
},
...on Actor {
preferredUsername,
__typename
}
}
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "search"))
assert hd(json_response(res, 200)["data"]["search"])["uuid"] == to_string(event.uuid)
assert hd(tl(json_response(res, 200)["data"]["search"]))["preferredUsername"] ==
actor.preferred_username
end
end
end

View File

@@ -0,0 +1,239 @@
defmodule MobilizonWeb.Resolvers.UserResolverTest do
use MobilizonWeb.ConnCase
alias Mobilizon.{Events, Actors}
alias Mobilizon.Actors.{Actor, User}
alias MobilizonWeb.AbsintheHelpers
import Mobilizon.Factory
use Bamboo.Test
@valid_actor_params %{email: "test@test.tld", password: "testest", username: "test"}
@non_existent_username "nonexistent"
describe "User Resolver" do
test "find_user/3 returns an user by it's id", context do
user = insert(:user)
query = """
{
user(id: "#{user.id}") {
email,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "user"))
assert json_response(res, 200)["data"]["user"]["email"] == user.email
query = """
{
user(id: "#{0}") {
email,
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "user"))
assert json_response(res, 200)["data"]["user"] == nil
assert hd(json_response(res, 200)["errors"])["message"] == "User with ID #{0} not found"
end
test "get_current_user/3 returns the current logged-in user", context do
user = insert(:user)
query = """
{
loggedUser {
id
}
}
"""
res =
context.conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "logged_user"))
assert json_response(res, 200)["data"]["loggedUser"] == nil
assert hd(json_response(res, 200)["errors"])["message"] ==
"You need to be logged-in to view current user"
res =
context.conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "logged_user"))
assert json_response(res, 200)["data"]["loggedUser"]["id"] == to_string(user.id)
end
end
@account_creation %{email: "test@demo.tld", password: "long password", username: "test_account"}
@account_creation_bad_email %{
email: "y@l@",
password: "long password",
username: "test_account"
}
test "test create_user_actor/3 creates an user", context do
mutation = """
mutation {
createUser(
email: "#{@account_creation.email}",
password: "#{@account_creation.password}",
username: "#{@account_creation.username}"
) {
preferred_username,
user {
email
}
}
}
"""
res =
context.conn
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["data"]["createUser"]["preferred_username"] ==
@account_creation.username
assert json_response(res, 200)["data"]["createUser"]["user"]["email"] ==
@account_creation.email
end
test "test create_user_actor/3 doesn't create an user with bad email", context do
mutation = """
mutation {
createUser(
email: "#{@account_creation_bad_email.email}",
password: "#{@account_creation.password}",
username: "#{@account_creation.username}"
) {
preferred_username,
user {
email
}
}
}
"""
res =
context.conn
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] == "Email doesn't fit required format"
end
@valid_actor_params %{email: "test@test.tld", password: "testest", username: "test"}
test "test validate_user/3 validates an user", context do
{:ok, actor} = Actors.register(@valid_actor_params)
mutation = """
mutation {
validateUser(
token: "#{actor.user.confirmation_token}"
) {
token,
user {
id
},
actor {
preferredUsername
}
}
}
"""
res =
context.conn
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["data"]["validateUser"]["actor"]["preferredUsername"] == @valid_actor_params.username
assert json_response(res, 200)["data"]["validateUser"]["user"]["id"] ==
to_string(actor.user.id)
end
test "test validate_user/3 with invalid token doesn't validate an user", context do
{:ok, actor} = Actors.register(@valid_actor_params)
mutation = """
mutation {
validateUser(
token: "no pass"
) {
token,
user {
id
},
actor {
preferredUsername
}
}
}
"""
res =
context.conn
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] == "Invalid token"
end
test "test resend_confirmation_email/3 with valid email resends an validation email", context do
{:ok, actor} = Actors.register(@valid_actor_params)
mutation = """
mutation {
resendConfirmationEmail(
email: "#{actor.user.email}"
)
}
"""
res =
context.conn
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] == "You requested again a confirmation email too soon"
# Hammer time !
Mobilizon.Actors.update_user(actor.user, %{
confirmation_sent_at: Timex.shift(actor.user.confirmation_sent_at, hours: -3)
})
res =
context.conn
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["data"]["resendConfirmationEmail"] == actor.user.email
assert_delivered_email Mobilizon.Email.User.confirmation_email(actor.user)
end
test "test resend_confirmation_email/3 with invalid email resends an validation email", context do
{:ok, actor} = Actors.register(@valid_actor_params)
mutation = """
mutation {
resendConfirmationEmail(
email: "oh no"
)
}
"""
res =
context.conn
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] == "No user to validate with this email was found"
end
end

View File

@@ -0,0 +1,18 @@
defmodule MobilizonWeb.ErrorViewTest do
use MobilizonWeb.ConnCase, async: true
# Bring render/3 and render_to_string/3 for testing custom views
import Phoenix.View
test "renders 404.html" do
assert render_to_string(MobilizonWeb.ErrorView, "404.html", []) == "Page not found"
end
test "render 500.html" do
assert render_to_string(MobilizonWeb.ErrorView, "500.html", []) == "Internal server error"
end
test "render any other" do
assert render_to_string(MobilizonWeb.ErrorView, "505.html", []) == "Internal server error"
end
end

View File

@@ -0,0 +1,3 @@
defmodule MobilizonWeb.LayoutViewTest do
use MobilizonWeb.ConnCase, async: true
end

View File

@@ -0,0 +1,3 @@
defmodule MobilizonWeb.PageViewTest do
use MobilizonWeb.ConnCase, async: true
end