defmodule Mix.Tasks.Mobilizon.UsersTest do use Mobilizon.DataCase import Mobilizon.Factory alias Mix.Tasks.Mobilizon.Users.{Delete, Modify, New, Show} alias Mobilizon.{Actors, Config, Users} alias Mobilizon.Actors.Actor alias Mobilizon.Service.Auth.MobilizonAuthenticator alias Mobilizon.Users.User Mix.shell(Mix.Shell.Process) @email "test@email.tld" describe "create user" do test "create with no options" do New.run([@email]) assert {:ok, %User{email: email, role: role, confirmed_at: confirmed_at, provider: nil}} = Users.get_user_by_email(@email) assert email == @email assert role == :user refute is_nil(confirmed_at) end test "create a moderator" do New.run([@email, "--moderator"]) assert {:ok, %User{email: email, role: role}} = Users.get_user_by_email(@email) assert email == @email assert role == :moderator end test "create an administrator" do New.run([@email, "--admin"]) assert {:ok, %User{email: email, role: role}} = Users.get_user_by_email(@email) assert email == @email assert role == :administrator end test "create with already used email" do insert(:user, email: @email) New.run([@email]) # Debug message assert_received {:mix_shell, :error, [message]} assert message =~ "[email: {\"This email is already used.\", [constraint: :unique, constraint_name: \"users_email_index\"]}]" assert_received {:mix_shell, :error, [message]} assert message =~ "User has not been created because of the above reason." end end describe "create user from external provider" do test "create user from ldap" do New.run([@email, "--provider", "ldap"]) assert {:ok, %User{email: @email, password: nil, provider: "ldap", confirmed_at: %DateTime{}}} = Users.get_user_by_email(@email) assert_received {:mix_shell, :info, [message]} assert message =~ "Warning: The ldap provider isn't currently configured as default authenticator." end test "create user from ldap when configured" do Config.put([Mobilizon.Service.Auth.Authenticator], Mobilizon.Service.Auth.LDAPAuthenticator) New.run([@email, "--provider", "ldap"]) assert {:ok, %User{email: @email, password: nil, provider: "ldap", confirmed_at: %DateTime{}}} = Users.get_user_by_email(@email) assert_received {:mix_shell, :info, [message]} refute message =~ "Warning: The ldap provider isn't currently configured as default authenticator." Config.put( [Mobilizon.Service.Auth.Authenticator], Mobilizon.Service.Auth.MobilizonAuthenticator ) end test "can't set --provider at the same time than --password" do New.run([@email, "--provider", "ldap", "--password", "random"]) assert {:ok, %User{email: @email, password: nil, provider: "ldap", confirmed_at: %DateTime{}}} = Users.get_user_by_email(@email) assert_received {:mix_shell, :error, [message]} assert message =~ "The --password and --provider options can't be specified at the same time." end end describe "create user and profile" do @preferred_username "toto" @name "Léo Pandaï" @converted_username "leo_pandai" test "create a profile with the user" do New.run([@email, "--profile-username", @preferred_username, "--profile-display-name", @name]) assert {:ok, %User{ email: email, role: role, confirmed_at: confirmed_at, id: user_id, default_actor_id: user_default_actor_id }} = Users.get_user_by_email(@email) assert %Actor{ preferred_username: @preferred_username, name: @name, domain: nil, user_id: ^user_id, id: actor_id } = Actors.get_local_actor_by_name(@preferred_username) assert user_default_actor_id == actor_id assert email == @email assert role == :user refute is_nil(confirmed_at) end test "create a profile from displayed name only" do New.run([@email, "--profile-display-name", @name]) assert {:ok, %User{ email: email, role: role, confirmed_at: confirmed_at, id: user_id, default_actor_id: user_default_actor_id }} = Users.get_user_by_email(@email) assert %Actor{ preferred_username: @converted_username, name: @name, domain: nil, user_id: ^user_id, id: actor_id } = Actors.get_local_actor_by_name(@converted_username) assert user_default_actor_id == actor_id assert email == @email assert role == :user refute is_nil(confirmed_at) end test "create a profile from username only" do New.run([@email, "--profile-username", @preferred_username]) assert {:ok, %User{ email: email, role: role, confirmed_at: confirmed_at, id: user_id, default_actor_id: user_default_actor_id }} = Users.get_user_by_email(@email) assert %Actor{ preferred_username: @preferred_username, name: @preferred_username, domain: nil, user_id: ^user_id, id: actor_id } = Actors.get_local_actor_by_name(@preferred_username) assert user_default_actor_id == actor_id assert email == @email assert role == :user refute is_nil(confirmed_at) end end describe "delete user" do test "delete existing user" do insert(:user, email: @email) Delete.run([@email, "-y"]) assert {:error, :user_not_found} = Users.get_user_by_email(@email) end test "full delete existing user" do insert(:user, email: @email) Delete.run([@email, "-y", "-k"]) assert {:ok, %User{disabled: true}} = Users.get_user_by_email(@email) end test "delete non-existing user" do Delete.run([@email, "-y"]) assert_received {:mix_shell, :error, [message]} assert message =~ "Error: No such user" end end describe "show user" do test "show existing user" do %User{confirmed_at: confirmed_at, role: role} = user = insert(:user, email: @email) actor1 = insert(:actor, user: user) actor2 = insert(:actor, user: user) output = "Informations for the user #{@email}:\n - account status: Activated on #{confirmed_at} (UTC)\n - Role: #{role}\n Identities (2):\n - @#{actor1.preferred_username} / #{actor1.name}\n - @#{actor2.preferred_username} / #{actor2.name}\n\n\n" Show.run([@email]) assert_received {:mix_shell, :info, [output_received]} assert output_received == output end test "show non-existing user" do Show.run([@email]) assert_received {:mix_shell, :error, [message]} assert message =~ "Error: No such user" end end describe "modify user" do test "modify existing user without any changes" do insert(:user, email: @email) Modify.run([@email]) assert_received {:mix_shell, :info, [output_received]} assert output_received == "No change has been made" end test "promote an user to moderator" do insert(:user, email: @email) Modify.run([@email, "--moderator"]) assert {:ok, %User{role: role}} = Users.get_user_by_email(@email) assert role == :moderator end test "promote an user to administrator" do insert(:user, email: @email) Modify.run([@email, "--admin"]) assert {:ok, %User{role: role}} = Users.get_user_by_email(@email) assert role == :administrator Modify.run([@email, "--user"]) assert {:ok, %User{role: role}} = Users.get_user_by_email(@email) assert role == :user end test "disable and enable an user" do user = insert(:user, email: @email) Modify.run([@email, "--disable"]) assert_received {:mix_shell, :info, [output_received]} assert output_received == "An user has been modified with the following information:\n - email: #{user.email}\n - Role: #{user.role}\n - account status: disabled\n" assert {:ok, %User{confirmed_at: confirmed_at}} = Users.get_user_by_email(@email) assert is_nil(confirmed_at) Modify.run([@email, "--enable"]) assert_received {:mix_shell, :info, [output_received]} assert {:ok, %User{confirmed_at: confirmed_at}} = Users.get_user_by_email(@email) assert output_received == "An user has been modified with the following information:\n - email: #{user.email}\n - Role: #{user.role}\n - account status: Activated on #{confirmed_at} (UTC)\n" refute is_nil(confirmed_at) Modify.run([@email, "--enable"]) assert {:ok, %User{confirmed_at: confirmed_at}} = Users.get_user_by_email(@email) refute is_nil(confirmed_at) assert_received {:mix_shell, :info, [output_received]} assert output_received == "No change has been made" end test "enable and disable at the same time" do Modify.run([@email, "--disable", "--enable"]) assert_received {:mix_shell, :error, [message]} assert message =~ "Can't use both --enable and --disable options at the same time." end @modified_email "modified@email.tld" test "change user's email" do user = insert(:user, email: @email) Modify.run([@email, "--email", @modified_email]) assert_received {:mix_shell, :info, [output_received]} assert {:ok, %User{confirmed_at: confirmed_at, email: @modified_email}} = Users.get_user_by_email(@modified_email) assert output_received == "An user has been modified with the following information:\n - email: #{@modified_email}\n - Role: #{user.role}\n - account status: Activated on #{confirmed_at} (UTC)\n" end @modified_password "new one" test "change an user's password" do insert(:user, email: @email) Modify.run([@email, "--password", @modified_password]) assert {:ok, %User{}} = MobilizonAuthenticator.login(@email, @modified_password) Modify.run([@email, "--password", "changed again"]) assert {:error, :bad_password} = MobilizonAuthenticator.login(@email, @modified_password) end end end