More test stuff
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
afb9b797ba
commit
534138f775
|
@ -9,6 +9,7 @@ defmodule Mobilizon.Actors do
|
||||||
alias Mobilizon.Actors.{Actor, Bot, Member, Follower, User}
|
alias Mobilizon.Actors.{Actor, Bot, Member, Follower, User}
|
||||||
|
|
||||||
alias Mobilizon.Service.ActivityPub
|
alias Mobilizon.Service.ActivityPub
|
||||||
|
import Exgravatar
|
||||||
|
|
||||||
@doc false
|
@doc false
|
||||||
def data() do
|
def data() do
|
||||||
|
@ -58,19 +59,12 @@ defmodule Mobilizon.Actors do
|
||||||
"""
|
"""
|
||||||
@spec get_actor_for_user(Mobilizon.Actors.User.t()) :: Mobilizon.Actors.Actor.t()
|
@spec get_actor_for_user(Mobilizon.Actors.User.t()) :: Mobilizon.Actors.Actor.t()
|
||||||
def get_actor_for_user(%Mobilizon.Actors.User{} = user) do
|
def get_actor_for_user(%Mobilizon.Actors.User{} = user) do
|
||||||
case user.default_actor_id do
|
with %User{default_actor: actor} = user when not is_nil(user) and not is_nil(actor) <-
|
||||||
nil -> get_first_actor_for_user(user)
|
Repo.preload(user, [:default_actor]) do
|
||||||
actor_id -> get_actor!(actor_id)
|
actor
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the first actor found for an user
|
|
||||||
# Useful when the user has not defined default actor
|
|
||||||
# Raises `Ecto.NoResultsError` if no Actor is found for this ID
|
|
||||||
defp get_first_actor_for_user(%Mobilizon.Actors.User{id: id} = _user) do
|
|
||||||
Repo.one!(from(a in Actor, where: a.user_id == ^id))
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_actor_with_everything!(id) do
|
def get_actor_with_everything!(id) do
|
||||||
actor = Repo.get!(Actor, id)
|
actor = Repo.get!(Actor, id)
|
||||||
Repo.preload(actor, [:organized_events, :followers, :followings])
|
Repo.preload(actor, [:organized_events, :followers, :followings])
|
||||||
|
@ -496,37 +490,26 @@ defmodule Mobilizon.Actors do
|
||||||
@doc """
|
@doc """
|
||||||
Register user
|
Register user
|
||||||
"""
|
"""
|
||||||
|
@spec register(map()) :: {:ok, Actor.t()} | {:error, String.t()}
|
||||||
def register(%{email: email, password: password, username: username}) do
|
def register(%{email: email, password: password, username: username}) do
|
||||||
key = :public_key.generate_key({:rsa, 2048, 65_537})
|
key = :public_key.generate_key({:rsa, 2048, 65_537})
|
||||||
entry = :public_key.pem_entry_encode(:RSAPrivateKey, key)
|
entry = :public_key.pem_entry_encode(:RSAPrivateKey, key)
|
||||||
pem = [entry] |> :public_key.pem_encode() |> String.trim_trailing()
|
pem = [entry] |> :public_key.pem_encode() |> String.trim_trailing()
|
||||||
|
|
||||||
import Exgravatar
|
with avatar <- gravatar(email),
|
||||||
|
actor_changeset <-
|
||||||
avatar_url = gravatar_url(email, default: "404")
|
|
||||||
|
|
||||||
avatar =
|
|
||||||
case HTTPoison.get(avatar_url) do
|
|
||||||
{:ok, %HTTPoison.Response{status_code: 200}} ->
|
|
||||||
avatar_url
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
|
|
||||||
with actor_changeset <-
|
|
||||||
Mobilizon.Actors.Actor.registration_changeset(%Mobilizon.Actors.Actor{}, %{
|
Mobilizon.Actors.Actor.registration_changeset(%Mobilizon.Actors.Actor{}, %{
|
||||||
preferred_username: username,
|
preferred_username: username,
|
||||||
domain: nil,
|
domain: nil,
|
||||||
keys: pem,
|
keys: pem,
|
||||||
avatar_url: avatar
|
avatar_url: avatar
|
||||||
}),
|
}),
|
||||||
{:ok, %Mobilizon.Actors.Actor{id: id} = actor} <- Mobilizon.Repo.insert(actor_changeset),
|
{:ok, %Mobilizon.Actors.Actor{} = actor} <- Mobilizon.Repo.insert(actor_changeset),
|
||||||
user_changeset <-
|
user_changeset <-
|
||||||
Mobilizon.Actors.User.registration_changeset(%Mobilizon.Actors.User{}, %{
|
Mobilizon.Actors.User.registration_changeset(%Mobilizon.Actors.User{}, %{
|
||||||
email: email,
|
email: email,
|
||||||
password: password,
|
password: password,
|
||||||
default_actor_id: id
|
default_actor: actor
|
||||||
}),
|
}),
|
||||||
{:ok, %Mobilizon.Actors.User{} = user} <- Mobilizon.Repo.insert(user_changeset) do
|
{:ok, %Mobilizon.Actors.User{} = user} <- Mobilizon.Repo.insert(user_changeset) do
|
||||||
{:ok, Map.put(actor, :user, user)}
|
{:ok, Map.put(actor, :user, user)}
|
||||||
|
@ -536,6 +519,22 @@ defmodule Mobilizon.Actors do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec gravatar(String.t()) :: String.t() | nil
|
||||||
|
defp gravatar(nil), do: nil
|
||||||
|
|
||||||
|
defp gravatar(email) do
|
||||||
|
avatar_url = gravatar_url(email, default: "404")
|
||||||
|
|
||||||
|
case HTTPoison.get(avatar_url) do
|
||||||
|
{:ok, %HTTPoison.Response{status_code: 200}} ->
|
||||||
|
avatar_url
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec handle_actor_user_changeset(Ecto.Changeset.t()) :: {:error, String.t()}
|
||||||
defp handle_actor_user_changeset(changeset) do
|
defp handle_actor_user_changeset(changeset) do
|
||||||
changeset =
|
changeset =
|
||||||
Ecto.Changeset.traverse_errors(changeset, fn
|
Ecto.Changeset.traverse_errors(changeset, fn
|
||||||
|
@ -543,7 +542,8 @@ defmodule Mobilizon.Actors do
|
||||||
msg -> msg
|
msg -> msg
|
||||||
end)
|
end)
|
||||||
|
|
||||||
{:error, hd(Map.get(changeset, :email))}
|
email_msg = Map.get(changeset, :email) || [:empty_email]
|
||||||
|
{:error, hd(email_msg)}
|
||||||
end
|
end
|
||||||
|
|
||||||
def register_bot_account(%{name: name, summary: summary}) do
|
def register_bot_account(%{name: name, summary: summary}) do
|
||||||
|
@ -611,6 +611,16 @@ defmodule Mobilizon.Actors do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec get_user_by_activation_token(String.t()) :: Actor.t()
|
||||||
|
def get_user_by_activation_token(token) do
|
||||||
|
Repo.one(
|
||||||
|
from(u in User,
|
||||||
|
where: u.confirmation_token == ^token,
|
||||||
|
preload: [:default_actor]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Updates a user.
|
Updates a user.
|
||||||
|
|
||||||
|
@ -645,18 +655,18 @@ defmodule Mobilizon.Actors do
|
||||||
Repo.delete(user)
|
Repo.delete(user)
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
# @doc """
|
||||||
Returns an `%Ecto.Changeset{}` for tracking user changes.
|
# Returns an `%Ecto.Changeset{}` for tracking user changes.
|
||||||
|
|
||||||
## Examples
|
# ## Examples
|
||||||
|
|
||||||
iex> change_user(%Mobilizon.Actors.User{})
|
# iex> change_user(%Mobilizon.Actors.User{})
|
||||||
%Ecto.Changeset{data: %Mobilizon.Actors.User{}}
|
# %Ecto.Changeset{data: %Mobilizon.Actors.User{}}
|
||||||
|
|
||||||
"""
|
# """
|
||||||
def change_user(%User{} = user) do
|
# def change_user(%User{} = user) do
|
||||||
User.changeset(user, %{})
|
# User.changeset(user, %{})
|
||||||
end
|
# end
|
||||||
|
|
||||||
alias Mobilizon.Actors.Member
|
alias Mobilizon.Actors.Member
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ defmodule Mobilizon.Actors.Service.Activation do
|
||||||
|
|
||||||
@doc false
|
@doc false
|
||||||
def check_confirmation_token(token) when is_binary(token) do
|
def check_confirmation_token(token) when is_binary(token) do
|
||||||
with %User{} = user <- Repo.get_by(User, confirmation_token: token),
|
with %User{} = user <- Actors.get_user_by_activation_token(token),
|
||||||
{:ok, %User{} = user} <-
|
{:ok, %User{} = user} <-
|
||||||
Actors.update_user(user, %{
|
Actors.update_user(user, %{
|
||||||
"confirmed_at" => DateTime.utc_now(),
|
"confirmed_at" => DateTime.utc_now(),
|
||||||
|
@ -20,7 +20,7 @@ defmodule Mobilizon.Actors.Service.Activation do
|
||||||
{:ok, user}
|
{:ok, user}
|
||||||
else
|
else
|
||||||
_err ->
|
_err ->
|
||||||
{:error, "Invalid token"}
|
{:error, :invalid_token}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ defmodule Mobilizon.Actors.Service.ResetPassword do
|
||||||
{:error, %Ecto.Changeset{errors: [password: {"registration.error.password_too_short", _}]}} ->
|
{:error, %Ecto.Changeset{errors: [password: {"registration.error.password_too_short", _}]}} ->
|
||||||
{:error, :password_too_short}
|
{:error, :password_too_short}
|
||||||
|
|
||||||
err ->
|
_err ->
|
||||||
{:error, :invalid_token}
|
{:error, :invalid_token}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,7 +13,7 @@ defmodule Mobilizon.Actors.User do
|
||||||
field(:password, :string, virtual: true)
|
field(:password, :string, virtual: true)
|
||||||
field(:role, :integer, default: 0)
|
field(:role, :integer, default: 0)
|
||||||
has_many(:actors, Actor)
|
has_many(:actors, Actor)
|
||||||
field(:default_actor_id, :integer)
|
has_one(:default_actor, Actor)
|
||||||
field(:confirmed_at, :utc_datetime)
|
field(:confirmed_at, :utc_datetime)
|
||||||
field(:confirmation_sent_at, :utc_datetime)
|
field(:confirmation_sent_at, :utc_datetime)
|
||||||
field(:confirmation_token, :string)
|
field(:confirmation_token, :string)
|
||||||
|
@ -29,7 +29,7 @@ defmodule Mobilizon.Actors.User do
|
||||||
|> cast(attrs, [
|
|> cast(attrs, [
|
||||||
:email,
|
:email,
|
||||||
:role,
|
:role,
|
||||||
:default_actor_id,
|
# :default_actor,
|
||||||
:password_hash,
|
:password_hash,
|
||||||
:confirmed_at,
|
:confirmed_at,
|
||||||
:confirmation_sent_at,
|
:confirmation_sent_at,
|
||||||
|
@ -52,7 +52,8 @@ defmodule Mobilizon.Actors.User do
|
||||||
struct
|
struct
|
||||||
|> changeset(params)
|
|> changeset(params)
|
||||||
|> cast(params, ~w(password)a, [])
|
|> cast(params, ~w(password)a, [])
|
||||||
|> validate_required([:email, :password, :default_actor_id])
|
|> put_assoc(:default_actor, params.default_actor)
|
||||||
|
|> validate_required([:email, :password])
|
||||||
|> validate_email()
|
|> validate_email()
|
||||||
|> validate_length(
|
|> validate_length(
|
||||||
:password,
|
:password,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
defmodule MobilizonWeb.Resolvers.User do
|
defmodule MobilizonWeb.Resolvers.User do
|
||||||
alias Mobilizon.Actors.{User, Actor}
|
alias Mobilizon.Actors.{User, Actor}
|
||||||
alias Mobilizon.Actors
|
alias Mobilizon.Actors
|
||||||
|
require Logger
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Find an user by it's ID
|
Find an user by it's ID
|
||||||
|
@ -56,11 +57,18 @@ defmodule MobilizonWeb.Resolvers.User do
|
||||||
Validate an user, get it's actor and a token
|
Validate an user, get it's actor and a token
|
||||||
"""
|
"""
|
||||||
def validate_user(_parent, %{token: token}, _resolution) do
|
def validate_user(_parent, %{token: token}, _resolution) do
|
||||||
with {:ok, %User{} = user} <-
|
with {:check_confirmation_token, {:ok, %User{} = user}} <-
|
||||||
Mobilizon.Actors.Service.Activation.check_confirmation_token(token),
|
{:check_confirmation_token,
|
||||||
%Actor{} = actor <- Actors.get_actor_for_user(user),
|
Mobilizon.Actors.Service.Activation.check_confirmation_token(token)},
|
||||||
{:ok, token, _} <- MobilizonWeb.Guardian.encode_and_sign(user) do
|
{:get_actor, %Actor{} = actor} <- {:get_actor, Actors.get_actor_for_user(user)},
|
||||||
|
{:guardian_encode_and_sign, {:ok, token, _}} <-
|
||||||
|
{:guardian_encode_and_sign, MobilizonWeb.Guardian.encode_and_sign(user)} do
|
||||||
{:ok, %{token: token, user: user, person: actor}}
|
{:ok, %{token: token, user: user, person: actor}}
|
||||||
|
else
|
||||||
|
err ->
|
||||||
|
Logger.info("Unable to validate user with token #{token}")
|
||||||
|
Logger.debug(inspect(err))
|
||||||
|
{:error, :validation_failed}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -116,8 +124,8 @@ defmodule MobilizonWeb.Resolvers.User do
|
||||||
def change_default_actor(_parent, %{preferred_username: username}, %{
|
def change_default_actor(_parent, %{preferred_username: username}, %{
|
||||||
context: %{current_user: user}
|
context: %{current_user: user}
|
||||||
}) do
|
}) do
|
||||||
with %Actor{id: id} <- Actors.get_local_actor_by_name(username) do
|
with %Actor{} = actor <- Actors.get_local_actor_by_name(username) do
|
||||||
Actors.update_user(user, %{default_actor_id: id})
|
Actors.update_user(user, %{default_actor: actor})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -177,8 +177,7 @@ defmodule MobilizonWeb.Schema do
|
||||||
description: "The user's list of profiles (identities)"
|
description: "The user's list of profiles (identities)"
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO: This shouldn't be an ID, but the actor itself
|
field(:default_actor, non_null(:person), description: "The user's default actor")
|
||||||
field(:default_actor_id, non_null(:integer), description: "The user's default actor")
|
|
||||||
|
|
||||||
field(:confirmed_at, :datetime,
|
field(:confirmed_at, :datetime,
|
||||||
description: "The datetime when the user was confirmed/activated"
|
description: "The datetime when the user was confirmed/activated"
|
||||||
|
|
|
@ -289,19 +289,9 @@ defmodule Mobilizon.ActorsTest do
|
||||||
describe "users" do
|
describe "users" do
|
||||||
alias Mobilizon.Actors.{User, Actor}
|
alias Mobilizon.Actors.{User, Actor}
|
||||||
|
|
||||||
@actor_valid_attrs %{
|
@valid_attrs %{email: "foo@bar.tld", password: "some password", username: "foo"}
|
||||||
description: "some description",
|
@update_attrs %{email: "foo@fighters.tld", password: "some updated password"}
|
||||||
display_name: "some display_name",
|
@invalid_attrs %{email: nil, password: nil, username: nil}
|
||||||
domain: "some domain",
|
|
||||||
keys: "some keys",
|
|
||||||
suspended: true,
|
|
||||||
uri: "some uri",
|
|
||||||
url: "some url",
|
|
||||||
preferred_username: "some username"
|
|
||||||
}
|
|
||||||
@valid_attrs %{email: "foo@bar.tld", password: "some password", role: 42}
|
|
||||||
@update_attrs %{email: "foo@fighters.tld", password: "some updated password", role: 43}
|
|
||||||
@invalid_attrs %{email: nil, password_hash: nil, role: nil}
|
|
||||||
|
|
||||||
test "list_users/0 returns all users" do
|
test "list_users/0 returns all users" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
@ -314,24 +304,23 @@ defmodule Mobilizon.ActorsTest do
|
||||||
assert user = Actors.get_user!(user.id)
|
assert user = Actors.get_user!(user.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "create_user/1 with valid data creates a user" do
|
# There's no create_user/1, just register/1
|
||||||
{:ok, %Actor{} = actor} = Actors.create_actor(@actor_valid_attrs)
|
test "register/1 with valid data creates a user" do
|
||||||
attrs = @valid_attrs |> Map.put(:actor_id, actor.id) |> Map.put(:default_actor_id, actor.id)
|
assert {:ok, %Actor{preferred_username: username, user: %User{email: email}}} =
|
||||||
assert {:ok, %User{} = user} = Actors.create_user(attrs)
|
Actors.register(@valid_attrs)
|
||||||
assert user.email == "foo@bar.tld"
|
|
||||||
assert user.role == 42
|
assert email == @valid_attrs.email
|
||||||
|
assert username == @valid_attrs.username
|
||||||
end
|
end
|
||||||
|
|
||||||
test "create_user/1 with invalid data returns error changeset" do
|
test "create_user/1 with invalid data returns error changeset" do
|
||||||
assert {:error, %Ecto.Changeset{}} = Actors.create_user(@invalid_attrs)
|
assert {:error, :empty_email} = Actors.register(@invalid_attrs)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "update_user/2 with valid data updates the user" do
|
test "update_user/2 with valid data updates the user" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
assert {:ok, user} = Actors.update_user(user, @update_attrs)
|
assert {:ok, %User{email: email}} = Actors.update_user(user, @update_attrs)
|
||||||
assert %User{} = user
|
assert email == "foo@fighters.tld"
|
||||||
assert user.email == "foo@fighters.tld"
|
|
||||||
assert user.role == 43
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "update_user/2 with invalid data returns error changeset" do
|
test "update_user/2 with invalid data returns error changeset" do
|
||||||
|
@ -346,10 +335,10 @@ defmodule Mobilizon.ActorsTest do
|
||||||
assert_raise Ecto.NoResultsError, fn -> Actors.get_user!(user.id) end
|
assert_raise Ecto.NoResultsError, fn -> Actors.get_user!(user.id) end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "change_user/1 returns a user changeset" do
|
# test "change_user/1 returns a user changeset" do
|
||||||
user = insert(:user)
|
# user = insert(:user)
|
||||||
assert %Ecto.Changeset{} = Actors.change_user(user)
|
# assert %Ecto.Changeset{} = Actors.change_user(user)
|
||||||
end
|
# end
|
||||||
|
|
||||||
@email "email@domain.tld"
|
@email "email@domain.tld"
|
||||||
@password "password"
|
@password "password"
|
||||||
|
|
|
@ -190,7 +190,7 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do
|
||||||
context.conn
|
context.conn
|
||||||
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
|
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
|
||||||
|
|
||||||
assert hd(json_response(res, 200)["errors"])["message"] == "Invalid token"
|
assert hd(json_response(res, 200)["errors"])["message"] == "validation_failed"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue