diff --git a/lib/mobilizon/actors/actors.ex b/lib/mobilizon/actors/actors.ex index e1ad14461..06ecd20c9 100644 --- a/lib/mobilizon/actors/actors.ex +++ b/lib/mobilizon/actors/actors.ex @@ -9,7 +9,6 @@ defmodule Mobilizon.Actors do alias Mobilizon.Repo alias Mobilizon.Actors.{Actor, Bot, Member, Follower} - alias Mobilizon.Users.User alias Mobilizon.Service.ActivityPub # import Exgravatar @@ -505,17 +504,6 @@ defmodule Mobilizon.Actors do [entry] |> :public_key.pem_encode() |> String.trim_trailing() end - @doc """ - Register user - """ - @spec register(map()) :: {:ok, User.t()} | {:error, String.t()} - def register(%{email: _email, password: _password} = args) do - with {:ok, %User{} = user} <- - %User{} |> User.registration_changeset(args) |> Mobilizon.Repo.insert() do - {:ok, user} - end - end - @doc """ Create a new person actor """ @@ -525,8 +513,13 @@ defmodule Mobilizon.Actors do pem = [entry] |> :public_key.pem_encode() |> String.trim_trailing() args = Map.put(args, :keys, pem) - actor = Mobilizon.Actors.Actor.registration_changeset(%Mobilizon.Actors.Actor{}, args) - Mobilizon.Repo.insert(actor) + with {:ok, %Actor{} = person} <- + %Actor{} + |> Actor.registration_changeset(args) + |> Repo.insert() do + Mobilizon.Events.create_feed_token(%{"user_id" => args["user_id"], "actor_id" => person.id}) + {:ok, person} + end end def register_bot_account(%{name: name, summary: summary}) do diff --git a/lib/mobilizon/events/events.ex b/lib/mobilizon/events/events.ex index 749db611a..42ae4b484 100644 --- a/lib/mobilizon/events/events.ex +++ b/lib/mobilizon/events/events.ex @@ -9,6 +9,7 @@ defmodule Mobilizon.Events do alias Mobilizon.Repo alias Mobilizon.Events.{Event, Comment, Participant} alias Mobilizon.Actors.Actor + alias Mobilizon.Users.User alias Mobilizon.Addresses.Address def data() do @@ -1192,6 +1193,32 @@ defmodule Mobilizon.Events do |> Repo.one!() end + @doc """ + Get feed tokens for an user + """ + @spec get_feed_tokens(User.t()) :: list(FeedTokens.t()) + def get_feed_tokens(%User{id: id}) do + from( + tk in FeedToken, + where: tk.user_id == ^id, + preload: [:actor, :user] + ) + |> Repo.all() + end + + @doc """ + Get feed tokens for an actor + """ + @spec get_feed_tokens(Actor.t()) :: list(FeedTokens.t()) + def get_feed_tokens(%Actor{id: id, domain: nil}) do + from( + tk in FeedToken, + where: tk.actor_id == ^id, + preload: [:actor, :user] + ) + |> Repo.all() + end + @doc """ Creates a feed token. @@ -1205,6 +1232,8 @@ defmodule Mobilizon.Events do """ def create_feed_token(attrs \\ %{}) do + attrs = Map.put(attrs, "token", Ecto.UUID.generate()) + %FeedToken{} |> FeedToken.changeset(attrs) |> Repo.insert() diff --git a/lib/mobilizon/events/feed_token.ex b/lib/mobilizon/events/feed_token.ex index 6af9e7a89..f4b55e477 100644 --- a/lib/mobilizon/events/feed_token.ex +++ b/lib/mobilizon/events/feed_token.ex @@ -9,8 +9,8 @@ defmodule Mobilizon.Events.FeedToken do alias Mobilizon.Users.User @primary_key false - schema "feed_token" do - field(:token, :string, primary_key: true) + schema "feed_tokens" do + field(:token, Ecto.UUID, primary_key: true) belongs_to(:actor, Actor) belongs_to(:user, User) diff --git a/lib/mobilizon/users/users.ex b/lib/mobilizon/users/users.ex index 719e824c4..1628cc670 100644 --- a/lib/mobilizon/users/users.ex +++ b/lib/mobilizon/users/users.ex @@ -21,6 +21,18 @@ defmodule Mobilizon.Users do queryable end + @doc """ + Register user + """ + @spec register(map()) :: {:ok, User.t()} | {:error, String.t()} + def register(%{email: _email, password: _password} = args) do + with {:ok, %User{} = user} <- + %User{} |> User.registration_changeset(args) |> Mobilizon.Repo.insert() do + Mobilizon.Events.create_feed_token(%{"user_id" => user.id}) + {:ok, user} + end + end + @doc """ Gets an user by it's email diff --git a/lib/mobilizon_web/resolvers/feed_token.ex b/lib/mobilizon_web/resolvers/feed_token.ex new file mode 100644 index 000000000..02ad34bc7 --- /dev/null +++ b/lib/mobilizon_web/resolvers/feed_token.ex @@ -0,0 +1,77 @@ +defmodule MobilizonWeb.Resolvers.FeedToken do + @moduledoc """ + Handles the feed tokens-related GraphQL calls + """ + require Logger + alias Mobilizon.Users.User + alias Mobilizon.Events + alias Mobilizon.Events.FeedToken + + @doc """ + Create an feed token for an user and a defined actor + """ + @spec create_feed_token(any(), map(), map()) :: {:ok, FeedToken.t()} | {:error, String.t()} + def create_feed_token(_parent, %{actor_id: actor_id}, %{ + context: %{current_user: %User{id: id} = user} + }) do + with {:is_owned, true, _actor} <- User.owns_actor(user, actor_id), + {:ok, feed_token} <- Events.create_feed_token(%{"user_id" => id, "actor_id" => actor_id}) do + {:ok, feed_token} + else + {:is_owned, false} -> + {:error, "Actor id is not owned by authenticated user"} + end + end + + @doc """ + Create an feed token for an user + """ + @spec create_feed_token(any(), map(), map()) :: {:ok, FeedToken.t()} + def create_feed_token(_parent, %{}, %{ + context: %{current_user: %User{id: id}} + }) do + with {:ok, feed_token} <- Events.create_feed_token(%{"user_id" => id}) do + {:ok, feed_token} + end + end + + @spec create_feed_token(any(), map(), map()) :: {:error, String.t()} + def create_feed_token(_parent, _args, %{}) do + {:error, "You are not allowed to create a feed token if not connected"} + end + + @doc """ + Delete a feed token + """ + @spec delete_feed_token(any(), map(), map()) :: {:ok, map()} | {:error, String.t()} + def delete_feed_token(_parent, %{token: token}, %{ + context: %{current_user: %User{id: id} = _user} + }) do + with {:ok, token} <- Ecto.UUID.cast(token), + {:no_token, %FeedToken{actor: actor, user: %User{} = user} = feed_token} <- + {:no_token, Events.get_feed_token(token)}, + {:token_from_user, true} <- {:token_from_user, id == user.id}, + {:ok, _} <- Events.delete_feed_token(feed_token) do + res = %{user: %{id: id}} + res = if is_nil(actor), do: res, else: Map.put(res, :actor, %{id: actor.id}) + {:ok, res} + else + {:error, nil} -> + {:error, "No such feed token"} + + :error -> + {:error, "Token is not a valid UUID"} + + {:no_token, _} -> + {:error, "Token does not exist"} + + {:token_from_user, false} -> + {:error, "You don't have permission to delete this token"} + end + end + + @spec delete_feed_token(any(), map(), map()) :: {:error, String.t()} + def delete_feed_token(_parent, _args, %{}) do + {:error, "You are not allowed to delete a feed token if not connected"} + end +end diff --git a/lib/mobilizon_web/resolvers/user.ex b/lib/mobilizon_web/resolvers/user.ex index df9c8669e..d746ce81c 100644 --- a/lib/mobilizon_web/resolvers/user.ex +++ b/lib/mobilizon_web/resolvers/user.ex @@ -70,7 +70,7 @@ defmodule MobilizonWeb.Resolvers.User do """ @spec create_user(any(), map(), any()) :: tuple() def create_user(_parent, args, _resolution) do - with {:ok, %User{} = user} <- Actors.register(args) do + with {:ok, %User{} = user} <- Users.register(args) do Activation.send_confirmation_email(user) {:ok, user} end diff --git a/lib/mobilizon_web/schema.ex b/lib/mobilizon_web/schema.ex index 65cebddc9..9d140130f 100644 --- a/lib/mobilizon_web/schema.ex +++ b/lib/mobilizon_web/schema.ex @@ -4,7 +4,7 @@ defmodule MobilizonWeb.Schema do """ use Absinthe.Schema - alias Mobilizon.{Actors, Events} + alias Mobilizon.{Actors, Events, Users} alias Mobilizon.Actors.{Actor, Follower, Member} alias Mobilizon.Events.{Event, Comment, Participant} @@ -104,6 +104,7 @@ defmodule MobilizonWeb.Schema do loader = Dataloader.new() |> Dataloader.add_source(Actors, Actors.data()) + |> Dataloader.add_source(Users, Users.data()) |> Dataloader.add_source(Events, Events.data()) Map.put(ctx, :loader, loader) @@ -144,6 +145,7 @@ defmodule MobilizonWeb.Schema do import_fields(:comment_mutations) import_fields(:participant_mutations) import_fields(:member_mutations) + import_fields(:feed_token_mutations) # @desc "Upload a picture" # field :upload_picture, :picture do diff --git a/lib/mobilizon_web/schema/actors/person.ex b/lib/mobilizon_web/schema/actors/person.ex index 2271c26fe..8fe4c8ddf 100644 --- a/lib/mobilizon_web/schema/actors/person.ex +++ b/lib/mobilizon_web/schema/actors/person.ex @@ -8,6 +8,8 @@ defmodule MobilizonWeb.Schema.Actors.PersonType do alias MobilizonWeb.Resolvers import MobilizonWeb.Schema.Utils + import_types(MobilizonWeb.Schema.Events.FeedTokenType) + @desc """ Represents a person identity """ @@ -41,6 +43,11 @@ defmodule MobilizonWeb.Schema.Actors.PersonType do field(:followersCount, :integer, description: "Number of followers for this actor") field(:followingCount, :integer, description: "Number of actors following this actor") + field(:feed_tokens, list_of(:feed_token), + resolve: dataloader(Events), + description: "A list of the feed tokens for this person" + ) + # This one should have a privacy setting field(:organized_events, list_of(:event), resolve: dataloader(Events), diff --git a/lib/mobilizon_web/schema/events/feed_token.ex b/lib/mobilizon_web/schema/events/feed_token.ex new file mode 100644 index 000000000..7be904907 --- /dev/null +++ b/lib/mobilizon_web/schema/events/feed_token.ex @@ -0,0 +1,51 @@ +defmodule MobilizonWeb.Schema.Events.FeedTokenType do + @moduledoc """ + Schema representation for Participant + """ + use Absinthe.Schema.Notation + import Absinthe.Resolution.Helpers, only: [dataloader: 1] + alias MobilizonWeb.Resolvers + alias Mobilizon.Users + alias Mobilizon.Actors + + @desc "Represents a participant to an event" + object :feed_token do + field( + :actor, + :actor, + resolve: dataloader(Actors), + description: "The event which the actor participates in" + ) + + field( + :user, + :user, + resolve: dataloader(Users), + description: "The actor that participates to the event" + ) + + field(:token, :string, description: "The role of this actor at this event") + end + + @desc "Represents a deleted feed_token" + object :deleted_feed_token do + field(:user, :deleted_object) + field(:actor, :deleted_object) + end + + object :feed_token_mutations do + @desc "Create a Feed Token" + field :create_feed_token, :feed_token do + arg(:actor_id, :integer) + + resolve(&Resolvers.FeedToken.create_feed_token/3) + end + + @desc "Delete a feed token" + field :delete_feed_token, :deleted_feed_token do + arg(:token, non_null(:string)) + + resolve(&Resolvers.FeedToken.delete_feed_token/3) + end + end +end diff --git a/lib/mobilizon_web/schema/user.ex b/lib/mobilizon_web/schema/user.ex index 24ec29ffa..86bbf8d73 100644 --- a/lib/mobilizon_web/schema/user.ex +++ b/lib/mobilizon_web/schema/user.ex @@ -3,6 +3,8 @@ defmodule MobilizonWeb.Schema.UserType do Schema representation for User """ use Absinthe.Schema.Notation + import Absinthe.Resolution.Helpers, only: [dataloader: 1] + alias Mobilizon.Events alias MobilizonWeb.Resolvers.User import MobilizonWeb.Schema.Utils @@ -36,6 +38,11 @@ defmodule MobilizonWeb.Schema.UserType do field(:reset_password_token, :string, description: "The token sent when requesting password token" ) + + field(:feed_tokens, list_of(:feed_token), + resolve: dataloader(Events), + description: "A list of the feed tokens for this user" + ) end @desc "Users list" diff --git a/priv/repo/migrations/20190307133518_feed_token_table.exs b/priv/repo/migrations/20190307133518_feed_token_table.exs index ce79de20a..9e1459dae 100644 --- a/priv/repo/migrations/20190307133518_feed_token_table.exs +++ b/priv/repo/migrations/20190307133518_feed_token_table.exs @@ -2,8 +2,8 @@ defmodule Mobilizon.Repo.Migrations.FeedTokenTable do use Ecto.Migration def change do - create table(:feed_token, primary_key: false) do - add(:token, :string, primary_key: true) + create table(:feed_tokens, primary_key: false) do + add(:token, Ecto.UUID.type(), primary_key: true) add(:actor_id, references(:actors, on_delete: :delete_all), null: true) add(:user_id, references(:users, on_delete: :delete_all), null: false) diff --git a/test/mobilizon/users/users_test.exs b/test/mobilizon/users/users_test.exs index 9284b23f1..a7ebceeb9 100644 --- a/test/mobilizon/users/users_test.exs +++ b/test/mobilizon/users/users_test.exs @@ -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 diff --git a/test/mobilizon_web/resolvers/feed_token_resolver_test.exs b/test/mobilizon_web/resolvers/feed_token_resolver_test.exs new file mode 100644 index 000000000..8c5d122c7 --- /dev/null +++ b/test/mobilizon_web/resolvers/feed_token_resolver_test.exs @@ -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 diff --git a/test/mobilizon_web/resolvers/user_resolver_test.exs b/test/mobilizon_web/resolvers/user_resolver_test.exs index 18879596b..2f2ee6e55 100644 --- a/test/mobilizon_web/resolvers/user_resolver_test.exs +++ b/test/mobilizon_web/resolvers/user_resolver_test.exs @@ -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, %{