From 8b3d0af04ca7954779308a9121d91d3b4cc35150 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Thu, 29 Nov 2018 17:43:22 +0100 Subject: [PATCH] Changes to the actor - user relation Now the GraphQL API replies mostly with users which have the default_actor property filled to show profile information Signed-off-by: Thomas Citharel --- lib/mobilizon/actors/actors.ex | 99 ++++++++++---- .../actors/service/reset_password.ex | 4 +- lib/mobilizon/actors/user.ex | 52 +++---- lib/mobilizon_web/resolvers/user.ex | 25 ++-- lib/mobilizon_web/schema.ex | 5 +- test/mobilizon/actors/actors_test.exs | 14 +- .../resolvers/category_resolver_test.exs | 10 +- .../resolvers/event_resolver_test.exs | 10 +- .../resolvers/person_resolver_test.exs | 7 +- .../resolvers/user_resolver_test.exs | 129 ++++++++++++------ 10 files changed, 232 insertions(+), 123 deletions(-) diff --git a/lib/mobilizon/actors/actors.ex b/lib/mobilizon/actors/actors.ex index 297f237d4..3bbd24e0b 100644 --- a/lib/mobilizon/actors/actors.ex +++ b/lib/mobilizon/actors/actors.ex @@ -59,12 +59,16 @@ defmodule Mobilizon.Actors do """ @spec get_actor_for_user(Mobilizon.Actors.User.t()) :: Mobilizon.Actors.Actor.t() def get_actor_for_user(%Mobilizon.Actors.User{} = user) do - with %User{default_actor: actor} = user when not is_nil(user) and not is_nil(actor) <- - Repo.preload(user, [:default_actor]) do - actor + case Repo.one(from(a in Actor, join: u in User, on: u.default_actor_id == a.id)) do + nil -> get_actors_for_user(user) |> hd + actor -> actor end end + def get_actors_for_user(%User{id: user_id}) do + Repo.all(from(a in Actor, where: a.user_id == ^user_id)) + end + def get_actor_with_everything!(id) do actor = Repo.get!(Actor, id) Repo.preload(actor, [:organized_events, :followers, :followings]) @@ -106,6 +110,13 @@ defmodule Mobilizon.Actors do |> Repo.update() end + def update_user_default_actor(user_id, actor_id) do + with from(u in User, where: u.id == ^user_id, update: [set: [default_actor_id: ^actor_id]]) + |> Repo.update_all([]) do + Repo.get!(User, user_id) |> Repo.preload([:default_actor]) + end + end + @doc """ Deletes a Actor. @@ -248,14 +259,25 @@ defmodule Mobilizon.Actors do @spec get_user_with_actors!(integer()) :: User.t() def get_user_with_actors!(id) do user = Repo.get!(User, id) - Repo.preload(user, :actors) + Repo.preload(user, [:actors, :default_actor]) end + @doc """ + Get user with it's actors by ID + """ @spec get_user_with_actors(integer()) :: User.t() def get_user_with_actors(id) do case Repo.get(User, id) do - nil -> {:error, "User with ID #{id} not found"} - user -> {:ok, Repo.preload(user, :actors)} + nil -> + {:error, "User with ID #{id} not found"} + + user -> + user = + user + |> Repo.preload([:actors, :default_actor]) + |> Map.put(:actors, get_actors_for_user(user)) + + {:ok, user} end end @@ -497,22 +519,21 @@ defmodule Mobilizon.Actors do pem = [entry] |> :public_key.pem_encode() |> String.trim_trailing() with avatar <- gravatar(email), - actor_changeset <- - Mobilizon.Actors.Actor.registration_changeset(%Mobilizon.Actors.Actor{}, %{ - preferred_username: username, - domain: nil, - keys: pem, - avatar_url: avatar - }), - {:ok, %Mobilizon.Actors.Actor{} = actor} <- Mobilizon.Repo.insert(actor_changeset), user_changeset <- - Mobilizon.Actors.User.registration_changeset(%Mobilizon.Actors.User{}, %{ + User.registration_changeset(%User{}, %{ email: email, password: password, - default_actor: actor + default_actor: %{ + preferred_username: username, + domain: nil, + keys: pem, + avatar_url: avatar + } }), - {:ok, %Mobilizon.Actors.User{} = user} <- Mobilizon.Repo.insert(user_changeset) do - {:ok, Map.put(actor, :user, user)} + {:ok, %User{default_actor: %Actor{} = actor, id: user_id} = user} <- + Mobilizon.Repo.insert(user_changeset), + {:ok, %Actor{} = _actor} <- update_actor(actor, %{user_id: user_id}) do + {:ok, Repo.preload(user, [:actors])} else {:error, %Ecto.Changeset{} = changeset} -> handle_actor_user_changeset(changeset) @@ -600,9 +621,20 @@ defmodule Mobilizon.Actors do def get_user_by_email(email, activated \\ nil) do query = case activated do - nil -> from(u in User, where: u.email == ^email) - true -> from(u in User, where: u.email == ^email and not is_nil(u.confirmed_at)) - false -> from(u in User, where: u.email == ^email and is_nil(u.confirmed_at)) + nil -> + from(u in User, where: u.email == ^email, preload: :default_actor) + + true -> + from(u in User, + where: u.email == ^email and not is_nil(u.confirmed_at), + preload: :default_actor + ) + + false -> + from(u in User, + where: u.email == ^email and is_nil(u.confirmed_at), + preload: :default_actor + ) end case Repo.one(query) do @@ -611,6 +643,9 @@ defmodule Mobilizon.Actors do end end + @doc """ + Get an user by it's activation token + """ @spec get_user_by_activation_token(String.t()) :: Actor.t() def get_user_by_activation_token(token) do Repo.one( @@ -621,6 +656,19 @@ defmodule Mobilizon.Actors do ) end + @doc """ + Get an user by it's reset password token + """ + @spec get_user_by_reset_password_token(String.t()) :: Actor.t() + def get_user_by_reset_password_token(token) do + Repo.one( + from(u in User, + where: u.reset_password_token == ^token, + preload: [:default_actor] + ) + ) + end + @doc """ Updates a user. @@ -634,9 +682,12 @@ defmodule Mobilizon.Actors do """ def update_user(%User{} = user, attrs) do - user - |> User.changeset(attrs) - |> Repo.update() + with {:ok, %User{} = user} <- + user + |> User.changeset(attrs) + |> Repo.update() do + {:ok, Repo.preload(user, [:default_actor])} + end end @doc """ diff --git a/lib/mobilizon/actors/service/reset_password.ex b/lib/mobilizon/actors/service/reset_password.ex index db09c17dc..0b03c6cd9 100644 --- a/lib/mobilizon/actors/service/reset_password.ex +++ b/lib/mobilizon/actors/service/reset_password.ex @@ -3,7 +3,7 @@ defmodule Mobilizon.Actors.Service.ResetPassword do require Logger - alias Mobilizon.{Mailer, Repo, Actors.User} + alias Mobilizon.{Mailer, Repo, Actors.User, Actors} alias Mobilizon.Email.User, as: UserEmail alias Mobilizon.Actors.Service.Tools @@ -12,7 +12,7 @@ defmodule Mobilizon.Actors.Service.ResetPassword do """ @spec check_reset_password_token(String.t(), String.t()) :: tuple def check_reset_password_token(password, token) do - with %User{} = user <- Repo.get_by(User, reset_password_token: token), + with %User{} = user <- Actors.get_user_by_reset_password_token(token), {:ok, %User{} = user} <- Repo.update( User.password_reset_changeset(user, %{ diff --git a/lib/mobilizon/actors/user.ex b/lib/mobilizon/actors/user.ex index 5ce95229d..5ba90441a 100644 --- a/lib/mobilizon/actors/user.ex +++ b/lib/mobilizon/actors/user.ex @@ -13,7 +13,7 @@ defmodule Mobilizon.Actors.User do field(:password, :string, virtual: true) field(:role, :integer, default: 0) has_many(:actors, Actor) - has_one(:default_actor, Actor) + belongs_to(:default_actor, Actor) field(:confirmed_at, :utc_datetime) field(:confirmation_sent_at, :utc_datetime) field(:confirmation_token, :string) @@ -25,34 +25,40 @@ defmodule Mobilizon.Actors.User do @doc false def changeset(%User{} = user, attrs) do - user - |> cast(attrs, [ - :email, - :role, - # :default_actor, - :password_hash, - :confirmed_at, - :confirmation_sent_at, - :confirmation_token, - :reset_password_sent_at, - :reset_password_token - ]) - |> validate_required([:email]) - |> unique_constraint(:email, message: "registration.error.email_already_used") - |> validate_format(:email, ~r/@/) - |> validate_length( - :password, - min: 6, - max: 100, - message: "registration.error.password_too_short" - ) + changeset = + user + |> cast(attrs, [ + :email, + :role, + :password_hash, + :confirmed_at, + :confirmation_sent_at, + :confirmation_token, + :reset_password_sent_at, + :reset_password_token + ]) + |> validate_required([:email]) + |> unique_constraint(:email, message: "registration.error.email_already_used") + |> validate_format(:email, ~r/@/) + |> validate_length( + :password, + min: 6, + max: 100, + message: "registration.error.password_too_short" + ) + + if Map.has_key?(attrs, :default_actor) do + put_assoc(changeset, :default_actor, attrs.default_actor) + else + changeset + end end def registration_changeset(struct, params) do struct |> changeset(params) |> cast(params, ~w(password)a, []) - |> put_assoc(:default_actor, params.default_actor) + |> cast_assoc(:default_actor) |> validate_required([:email, :password]) |> validate_email() |> validate_length( diff --git a/lib/mobilizon_web/resolvers/user.ex b/lib/mobilizon_web/resolvers/user.ex index f23eb9bc1..236cec39d 100644 --- a/lib/mobilizon_web/resolvers/user.ex +++ b/lib/mobilizon_web/resolvers/user.ex @@ -26,9 +26,8 @@ defmodule MobilizonWeb.Resolvers.User do """ def login_user(_parent, %{email: email, password: password}, _resolution) do with {:ok, %User{} = user} <- Actors.get_user_by_email(email, true), - {:ok, token, _} <- Actors.authenticate(%{user: user, password: password}), - %Actor{} = actor <- Actors.get_actor_for_user(user) do - {:ok, %{token: token, user: user, person: actor}} + {:ok, token, _} <- Actors.authenticate(%{user: user, password: password}) do + {:ok, %{token: token, user: user}} else {:error, :user_not_found} -> {:error, "User with email not found"} @@ -47,9 +46,9 @@ defmodule MobilizonWeb.Resolvers.User do """ @spec create_user_actor(any(), map(), any()) :: tuple() def create_user_actor(_parent, args, _resolution) do - with {:ok, %Actor{user: user} = actor} <- Actors.register(args) do + with {:ok, %User{} = user} <- Actors.register(args) do Mobilizon.Actors.Service.Activation.send_confirmation_email(user) - {:ok, actor} + {:ok, user} end end @@ -114,9 +113,8 @@ defmodule MobilizonWeb.Resolvers.User do def reset_password(_parent, %{password: password, token: token}, _resolution) do with {:ok, %User{} = user} <- Mobilizon.Actors.Service.ResetPassword.check_reset_password_token(password, token), - %Actor{} = actor <- Actors.get_actor_for_user(user), {:ok, token, _} <- MobilizonWeb.Guardian.encode_and_sign(user) do - {:ok, %{token: token, user: user, actor: actor}} + {:ok, %{token: token, user: user}} end end @@ -124,8 +122,17 @@ defmodule MobilizonWeb.Resolvers.User do def change_default_actor(_parent, %{preferred_username: username}, %{ context: %{current_user: user} }) do - with %Actor{} = actor <- Actors.get_local_actor_by_name(username) do - Actors.update_user(user, %{default_actor: actor}) + with %Actor{id: actor_id} <- Actors.get_local_actor_by_name(username), + {:user_actor, true} <- + {:user_actor, actor_id in Enum.map(Actors.get_actors_for_user(user), & &1.id)}, + %User{} = user <- Actors.update_user_default_actor(user.id, actor_id) do + {:ok, user} + else + {:user_actor, _} -> + {:error, :actor_not_from_user} + + _err -> + {:error, :unable_to_change_default_actor} end end end diff --git a/lib/mobilizon_web/schema.ex b/lib/mobilizon_web/schema.ex index 1dfe494df..b5754354f 100644 --- a/lib/mobilizon_web/schema.ex +++ b/lib/mobilizon_web/schema.ex @@ -202,7 +202,6 @@ defmodule MobilizonWeb.Schema do object :login do field(:token, non_null(:string), description: "A JWT Token for this session") field(:user, non_null(:user), description: "The user associated to this session") - field(:person, non_null(:person), description: "The person associated to this session") end @desc "An event" @@ -480,8 +479,8 @@ defmodule MobilizonWeb.Schema do resolve(&Resolvers.Category.create_category/3) end - @desc "Create an user (returns an actor)" - field :create_user, type: :person do + @desc "Create an user" + field :create_user, type: :user do arg(:email, non_null(:string)) arg(:password, non_null(:string)) arg(:username, non_null(:string)) diff --git a/test/mobilizon/actors/actors_test.exs b/test/mobilizon/actors/actors_test.exs index d2ccdb9e0..c88708cc6 100644 --- a/test/mobilizon/actors/actors_test.exs +++ b/test/mobilizon/actors/actors_test.exs @@ -306,15 +306,17 @@ defmodule Mobilizon.ActorsTest do # There's no create_user/1, just register/1 test "register/1 with valid data creates a user" do - assert {:ok, %Actor{preferred_username: username, user: %User{email: email}}} = - Actors.register(@valid_attrs) + assert {:ok, + %User{email: email, default_actor: %Actor{preferred_username: username} = actor} = + user} = Actors.register(@valid_attrs) assert email == @valid_attrs.email assert username == @valid_attrs.username + assert [actor.id] == Actors.get_actors_for_user(user) |> Enum.map(& &1.id) end test "create_user/1 with invalid data returns error changeset" do - assert {:error, :empty_email} = Actors.register(@invalid_attrs) + assert {:error, "can't be blank"} = Actors.register(@invalid_attrs) end test "update_user/2 with valid data updates the user" do @@ -343,7 +345,7 @@ defmodule Mobilizon.ActorsTest do @email "email@domain.tld" @password "password" test "authenticate/1 checks the user's password" do - {:ok, %Actor{user: user} = _actor} = + {:ok, %User{} = user} = Actors.register(%{email: @email, password: @password, username: "yolo"}) assert {:ok, _, _} = Actors.authenticate(%{user: user, password: @password}) @@ -353,7 +355,7 @@ defmodule Mobilizon.ActorsTest do end test "get_user_by_email/1 finds an user by it's email" do - {:ok, %Actor{user: %User{email: email} = user} = _actor} = + {:ok, %User{email: email} = user} = Actors.register(%{email: @email, password: @password, username: "yolo"}) assert email == @email @@ -363,7 +365,7 @@ defmodule Mobilizon.ActorsTest do end test "get_user_by_email/1 finds an activated user by it's email" do - {:ok, %Actor{user: user}} = + {:ok, %User{} = user} = Actors.register(%{email: @email, password: @password, username: "yolo"}) {:ok, %User{id: id}} = Actors.get_user_by_email(@email, false) diff --git a/test/mobilizon_web/resolvers/category_resolver_test.exs b/test/mobilizon_web/resolvers/category_resolver_test.exs index 63a2ac20a..7bf7d8a01 100644 --- a/test/mobilizon_web/resolvers/category_resolver_test.exs +++ b/test/mobilizon_web/resolvers/category_resolver_test.exs @@ -1,15 +1,15 @@ defmodule MobilizonWeb.Resolvers.CategoryResolverTest do use MobilizonWeb.ConnCase alias Mobilizon.Actors - alias Mobilizon.Actors.Actor + alias Mobilizon.Actors.{Actor, User} alias MobilizonWeb.AbsintheHelpers import Mobilizon.Factory setup %{conn: conn} do - {:ok, %Actor{} = actor} = + {:ok, %User{default_actor: %Actor{} = actor} = user} = Actors.register(%{email: "test@test.tld", password: "testest", username: "test"}) - {:ok, conn: conn, actor: actor} + {:ok, conn: conn, actor: actor, user: user} end describe "Category Resolver" do @@ -38,7 +38,7 @@ defmodule MobilizonWeb.Resolvers.CategoryResolverTest do end # We can't test an upload…yet? - # test "create_category/3 creates a category", %{conn: conn, actor: actor} do + # test "create_category/3 creates a category", %{conn: conn, actor: actor, user: user} do # mutation = """ # mutation { # createCategory(title: "my category", description: "my desc") { @@ -51,7 +51,7 @@ defmodule MobilizonWeb.Resolvers.CategoryResolverTest do # res = # conn - # |> auth_conn(actor.user) + # |> auth_conn(user) # |> post("/api", AbsintheHelpers.mutation_skeleton(mutation)) # assert json_response(res, 200)["data"]["createCategory"]["title"] == "my category" diff --git a/test/mobilizon_web/resolvers/event_resolver_test.exs b/test/mobilizon_web/resolvers/event_resolver_test.exs index 1466a5066..ec18000a6 100644 --- a/test/mobilizon_web/resolvers/event_resolver_test.exs +++ b/test/mobilizon_web/resolvers/event_resolver_test.exs @@ -1,17 +1,17 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do use MobilizonWeb.ConnCase alias Mobilizon.{Events, Actors} - alias Mobilizon.Actors.Actor + alias Mobilizon.Actors.{Actor, User} 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} = + {:ok, %User{default_actor: %Actor{} = actor} = user} = Actors.register(%{email: "test@test.tld", password: "testest", username: "test"}) - {:ok, conn: conn, actor: actor} + {:ok, conn: conn, actor: actor, user: user} end describe "Event Resolver" do @@ -108,7 +108,7 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do ] end - test "create_event/3 creates an event", %{conn: conn, actor: actor} do + test "create_event/3 creates an event", %{conn: conn, actor: actor, user: user} do category = insert(:category) mutation = """ @@ -129,7 +129,7 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do res = conn - |> auth_conn(actor.user) + |> auth_conn(user) |> post("/api", AbsintheHelpers.mutation_skeleton(mutation)) assert json_response(res, 200)["data"]["createEvent"]["title"] == "come to my event" diff --git a/test/mobilizon_web/resolvers/person_resolver_test.exs b/test/mobilizon_web/resolvers/person_resolver_test.exs index 0b5ca25a8..6f850c5df 100644 --- a/test/mobilizon_web/resolvers/person_resolver_test.exs +++ b/test/mobilizon_web/resolvers/person_resolver_test.exs @@ -1,6 +1,7 @@ defmodule MobilizonWeb.Resolvers.PersonResolverTest do use MobilizonWeb.ConnCase alias Mobilizon.Actors + alias Mobilizon.Actors.{User, Actor} alias MobilizonWeb.AbsintheHelpers @valid_actor_params %{email: "test@test.tld", password: "testest", username: "test"} @@ -8,7 +9,7 @@ defmodule MobilizonWeb.Resolvers.PersonResolverTest do describe "Person Resolver" do test "find_actor/3 returns a person by it's username", context do - {:ok, actor} = Actors.register(@valid_actor_params) + {:ok, %User{default_actor: %Actor{} = actor} = _user} = Actors.register(@valid_actor_params) query = """ { @@ -44,7 +45,7 @@ defmodule MobilizonWeb.Resolvers.PersonResolverTest do end test "get_current_person/3 returns the current logged-in actor", context do - {:ok, actor} = Actors.register(@valid_actor_params) + {:ok, %User{default_actor: %Actor{} = actor} = user} = Actors.register(@valid_actor_params) query = """ { @@ -66,7 +67,7 @@ defmodule MobilizonWeb.Resolvers.PersonResolverTest do res = context.conn - |> auth_conn(actor.user) + |> auth_conn(user) |> get("/api", AbsintheHelpers.query_skeleton(query, "logged_person")) assert json_response(res, 200)["data"]["loggedPerson"]["preferredUsername"] == diff --git a/test/mobilizon_web/resolvers/user_resolver_test.exs b/test/mobilizon_web/resolvers/user_resolver_test.exs index adef2d4e2..54d26bbaa 100644 --- a/test/mobilizon_web/resolvers/user_resolver_test.exs +++ b/test/mobilizon_web/resolvers/user_resolver_test.exs @@ -7,6 +7,7 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do use Bamboo.Test @valid_actor_params %{email: "test@test.tld", password: "testest", username: "test"} + @valid_single_actor_params %{preferred_username: "test2", keys: "yolo"} describe "Resolver: Get an user" do test "find_user/3 returns an user by it's id", context do @@ -91,10 +92,10 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do password: "#{@account_creation.password}", username: "#{@account_creation.username}" ) { - preferred_username, - user { - email - } + default_actor { + preferred_username, + }, + email } } """ @@ -103,11 +104,10 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do context.conn |> post("/api", AbsintheHelpers.mutation_skeleton(mutation)) - assert json_response(res, 200)["data"]["createUser"]["preferred_username"] == + assert json_response(res, 200)["data"]["createUser"]["default_actor"]["preferred_username"] == @account_creation.username - assert json_response(res, 200)["data"]["createUser"]["user"]["email"] == - @account_creation.email + assert json_response(res, 200)["data"]["createUser"]["email"] == @account_creation.email end test "test create_user_actor/3 doesn't create an user with bad email", context do @@ -118,10 +118,10 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do password: "#{@account_creation.password}", username: "#{@account_creation.username}" ) { - preferred_username, - user { - email - } + default_actor { + preferred_username, + }, + email, } } """ @@ -138,20 +138,20 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do describe "Resolver: Validate an user" do @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) + {:ok, %User{default_actor: %Actor{} = _actor} = user} = Actors.register(@valid_actor_params) mutation = """ mutation { validateUser( - token: "#{actor.user.confirmation_token}" + token: "#{user.confirmation_token}" ) { token, user { - id + id, + default_actor { + preferredUsername + } }, - person { - preferredUsername - } } } """ @@ -160,15 +160,16 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do context.conn |> post("/api", AbsintheHelpers.mutation_skeleton(mutation)) - assert json_response(res, 200)["data"]["validateUser"]["person"]["preferredUsername"] == - @valid_actor_params.username + assert json_response(res, 200)["data"]["validateUser"]["user"]["default_actor"][ + "preferredUsername" + ] == @valid_actor_params.username - assert json_response(res, 200)["data"]["validateUser"]["user"]["id"] == - to_string(actor.user.id) + assert json_response(res, 200)["data"]["validateUser"]["user"]["id"] == to_string(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) + {:ok, %User{default_actor: %Actor{} = _actor} = _user} = + Actors.register(@valid_actor_params) mutation = """ mutation { @@ -177,11 +178,11 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do ) { token, user { - id + id, + default_actor { + preferredUsername + } }, - person { - preferredUsername - } } } """ @@ -197,12 +198,12 @@ 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, actor} = Actors.register(@valid_actor_params) + {:ok, %User{default_actor: %Actor{} = _actor} = user} = Actors.register(@valid_actor_params) mutation = """ mutation { resendConfirmationEmail( - email: "#{actor.user.email}" + email: "#{user.email}" ) } """ @@ -215,21 +216,22 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do "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) + Mobilizon.Actors.update_user(user, %{ + confirmation_sent_at: Timex.shift(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)) + assert json_response(res, 200)["data"]["resendConfirmationEmail"] == user.email + assert_delivered_email(Mobilizon.Email.User.confirmation_email(user)) end test "test resend_confirmation_email/3 with invalid email resends an validation email", context do - {:ok, _actor} = Actors.register(@valid_actor_params) + {:ok, %User{default_actor: %Actor{} = _actor} = _user} = + Actors.register(@valid_actor_params) mutation = """ mutation { @@ -365,7 +367,7 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do describe "Resolver: Login an user" do test "test login_user/3 with valid credentials", context do - {:ok, %Actor{user: user}} = Actors.register(@valid_actor_params) + {:ok, %User{} = user} = Actors.register(@valid_actor_params) {:ok, %User{} = _user} = Actors.update_user(user, %{ @@ -381,8 +383,10 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do password: "#{@valid_actor_params.password}", ) { token, - person { - preferred_username, + user { + default_actor { + preferred_username, + } } } } @@ -394,11 +398,11 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do assert login = json_response(res, 200)["data"]["login"] assert Map.has_key?(login, "token") && not is_nil(login["token"]) - assert login["person"]["preferred_username"] == @valid_actor_params.username + assert login["user"]["default_actor"]["preferred_username"] == @valid_actor_params.username end test "test login_user/3 with invalid password", context do - {:ok, %Actor{user: user}} = Actors.register(@valid_actor_params) + {:ok, %User{} = user} = Actors.register(@valid_actor_params) {:ok, %User{} = _user} = Actors.update_user(user, %{ @@ -414,8 +418,10 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do password: "bad password", ) { token, - person { - preferred_username, + user { + default_actor { + preferred_username, + } } } } @@ -429,7 +435,7 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do end test "test login_user/3 with invalid email", context do - {:ok, %Actor{user: user}} = Actors.register(@valid_actor_params) + {:ok, %User{} = user} = Actors.register(@valid_actor_params) {:ok, %User{} = _user} = Actors.update_user(user, %{ @@ -445,8 +451,10 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do password: "bad password", ) { token, - person { - preferred_username, + user { + default_actor { + preferred_username, + } } } } @@ -459,4 +467,39 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do assert hd(json_response(res, 200)["errors"])["message"] == "User with email not found" end end + + describe "Resolver: change default actor for user" do + test "test change_default_actor/3 with valid actor", context do + # Prepare user with two actors + assert {:ok, %User{id: user_id, default_actor: %Actor{} = actor} = user} = + Actors.register(@valid_actor_params) + + assert {:ok, %User{actors: actors}} = Actors.get_user_with_actors(user_id) + + actor_params = @valid_single_actor_params |> Map.put(:user_id, user_id) + assert {:ok, %Actor{} = actor2} = Actors.create_actor(actor_params) + + assert {:ok, %User{actors: actors}} = Actors.get_user_with_actors(user_id) + assert length(actors) == 2 + + mutation = """ + mutation { + changeDefaultActor(preferred_username: "#{actor2.preferred_username}") { + default_actor { + preferred_username + } + } + } + """ + + res = + context.conn + |> auth_conn(user) + |> post("/api", AbsintheHelpers.mutation_skeleton(mutation)) + + assert json_response(res, 200)["data"]["changeDefaultActor"]["default_actor"][ + "preferred_username" + ] == actor2.preferred_username + end + end end