Add GraphQL support to handle FeedTokens

Closes #88

Automatically create tokens for new users and actors

Closes #89

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel
2019-03-08 18:52:27 +01:00
parent c61c75163f
commit 99ac6ef100
14 changed files with 541 additions and 31 deletions

View File

@@ -1,7 +1,6 @@
defmodule Mobilizon.UsersTest do
use Mobilizon.DataCase
alias Mobilizon.Actors
alias Mobilizon.Users
alias Mobilizon.Users.User
import Mobilizon.Factory
@@ -25,7 +24,7 @@ defmodule Mobilizon.UsersTest do
# There's no create_user/1, just register/1
test "register/1 with valid data creates a user" do
assert {:ok, %User{email: email} = user} = Actors.register(@valid_attrs)
assert {:ok, %User{email: email} = user} = Users.register(@valid_attrs)
assert email == @valid_attrs.email
end
@@ -38,7 +37,7 @@ defmodule Mobilizon.UsersTest do
email: {"can't be blank", [validation: :required]}
],
valid?: false
}} = Actors.register(@invalid_attrs)
}} = Users.register(@invalid_attrs)
end
test "update_user/2 with valid data updates the user" do
@@ -67,7 +66,7 @@ defmodule Mobilizon.UsersTest do
@email "email@domain.tld"
@password "password"
test "authenticate/1 checks the user's password" do
{:ok, %User{} = user} = Actors.register(%{email: @email, password: @password})
{:ok, %User{} = user} = Users.register(%{email: @email, password: @password})
assert {:ok, _, _} = Users.authenticate(%{user: user, password: @password})
@@ -76,7 +75,7 @@ defmodule Mobilizon.UsersTest do
end
test "get_user_by_email/1 finds an user by it's email" do
{:ok, %User{email: email} = user} = Actors.register(%{email: @email, password: @password})
{:ok, %User{email: email} = user} = Users.register(%{email: @email, password: @password})
assert email == @email
{:ok, %User{id: id}} = Users.get_user_by_email(@email)
@@ -85,7 +84,7 @@ defmodule Mobilizon.UsersTest do
end
test "get_user_by_email/1 finds an activated user by it's email" do
{:ok, %User{} = user} = Actors.register(%{email: @email, password: @password})
{:ok, %User{} = user} = Users.register(%{email: @email, password: @password})
{:ok, %User{id: id}} = Users.get_user_by_email(@email, false)
assert id == user.id

View File

@@ -0,0 +1,333 @@
defmodule MobilizonWeb.Resolvers.FeedTokenResolverTest do
use MobilizonWeb.ConnCase
alias MobilizonWeb.AbsintheHelpers
import Mobilizon.Factory
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"] == 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"] == user.id
assert json_response(res, 200)["data"]["deleteFeedToken"]["actor"]["id"] == 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

@@ -394,7 +394,7 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do
describe "Resolver: Validate an user" do
@valid_actor_params %{email: "test@test.tld", password: "testest"}
test "test validate_user/3 validates an user", context do
{:ok, %User{} = user} = Actors.register(@valid_actor_params)
{:ok, %User{} = user} = Users.register(@valid_actor_params)
mutation = """
mutation {
@@ -443,7 +443,7 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do
describe "Resolver: Resend confirmation emails" do
test "test resend_confirmation_email/3 with valid email resends an validation email",
context do
{:ok, %User{} = user} = Actors.register(%{email: "toto@tata.tld", password: "p4ssw0rd"})
{:ok, %User{} = user} = Users.register(%{email: "toto@tata.tld", password: "p4ssw0rd"})
mutation = """
mutation {
@@ -531,7 +531,7 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do
describe "Resolver: Reset user's password" do
test "test reset_password/3 with valid email", context do
{:ok, %User{} = user} = Actors.register(%{email: "toto@tata.tld", password: "p4ssw0rd"})
{:ok, %User{} = user} = Users.register(%{email: "toto@tata.tld", password: "p4ssw0rd"})
%Actor{} = insert(:actor, user: user)
{:ok, _email_sent} = ResetPassword.send_password_reset_email(user)
%User{reset_password_token: reset_password_token} = Mobilizon.Users.get_user!(user.id)
@@ -611,7 +611,7 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do
describe "Resolver: Login an user" do
test "test login_user/3 with valid credentials", context do
{:ok, %User{} = user} = Actors.register(%{email: "toto@tata.tld", password: "p4ssw0rd"})
{:ok, %User{} = user} = Users.register(%{email: "toto@tata.tld", password: "p4ssw0rd"})
{:ok, %User{} = _user} =
Users.update_user(user, %{
@@ -643,7 +643,7 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do
end
test "test login_user/3 with invalid password", context do
{:ok, %User{} = user} = Actors.register(%{email: "toto@tata.tld", password: "p4ssw0rd"})
{:ok, %User{} = user} = Users.register(%{email: "toto@tata.tld", password: "p4ssw0rd"})
{:ok, %User{} = _user} =
Users.update_user(user, %{