update tests

This commit is contained in:
shibao 2022-02-25 21:53:15 -05:00
parent 80708d9be3
commit 5138fa1c6e
15 changed files with 506 additions and 172 deletions

View File

@ -1,9 +1,14 @@
defmodule Lokal.AccountsTest do
use Lokal.DataCase
@moduledoc """
This tests the accounts module
"""
use Lokal.DataCase
alias Lokal.Accounts
import Lokal.AccountsFixtures
alias Lokal.Accounts.{User, UserToken}
alias Ecto.Changeset
@moduletag :accounts_test
describe "get_user_by_email/1" do
test "does not return the user if the email does not exist" do
@ -58,7 +63,8 @@ defmodule Lokal.AccountsTest do
end
test "validates email and password when given" do
{:error, changeset} = Accounts.register_user(%{email: "not valid", password: "not valid"})
{:error, changeset} =
Accounts.register_user(%{"email" => "not valid", "password" => "not valid"})
assert %{
email: ["must have the @ sign and no spaces"],
@ -68,24 +74,27 @@ defmodule Lokal.AccountsTest do
test "validates maximum values for email and password for security" do
too_long = String.duplicate("db", 100)
{:error, changeset} = Accounts.register_user(%{email: too_long, password: too_long})
{:error, changeset} = Accounts.register_user(%{"email" => too_long, "password" => too_long})
assert "should be at most 160 character(s)" in errors_on(changeset).email
assert "should be at most 80 character(s)" in errors_on(changeset).password
end
test "validates email uniqueness" do
%{email: email} = user_fixture()
{:error, changeset} = Accounts.register_user(%{email: email})
{:error, changeset} = Accounts.register_user(%{"email" => email})
assert "has already been taken" in errors_on(changeset).email
# Now try with the upper cased email too, to check that email case is ignored.
{:error, changeset} = Accounts.register_user(%{email: String.upcase(email)})
{:error, changeset} = Accounts.register_user(%{"email" => String.upcase(email)})
assert "has already been taken" in errors_on(changeset).email
end
test "registers users with a hashed password" do
email = unique_user_email()
{:ok, user} = Accounts.register_user(%{email: email, password: valid_user_password()})
{:ok, user} =
Accounts.register_user(%{"email" => email, "password" => valid_user_password()})
assert user.email == email
assert is_binary(user.hashed_password)
assert is_nil(user.confirmed_at)
@ -95,7 +104,7 @@ defmodule Lokal.AccountsTest do
describe "change_user_registration/2" do
test "returns a changeset" do
assert %Ecto.Changeset{} = changeset = Accounts.change_user_registration(%User{})
assert %Changeset{} = changeset = Accounts.change_user_registration(%User{})
assert changeset.required == [:password, :email]
end
@ -115,7 +124,7 @@ defmodule Lokal.AccountsTest do
describe "change_user_email/2" do
test "returns a user changeset" do
assert %Ecto.Changeset{} = changeset = Accounts.change_user_email(%User{})
assert %Changeset{} = changeset = Accounts.change_user_email(%User{})
assert changeset.required == [:email]
end
end
@ -132,7 +141,7 @@ defmodule Lokal.AccountsTest do
test "validates email", %{user: user} do
{:error, changeset} =
Accounts.apply_user_email(user, valid_user_password(), %{email: "not valid"})
Accounts.apply_user_email(user, valid_user_password(), %{"email" => "not valid"})
assert %{email: ["must have the @ sign and no spaces"]} = errors_on(changeset)
end
@ -141,7 +150,7 @@ defmodule Lokal.AccountsTest do
too_long = String.duplicate("db", 100)
{:error, changeset} =
Accounts.apply_user_email(user, valid_user_password(), %{email: too_long})
Accounts.apply_user_email(user, valid_user_password(), %{"email" => too_long})
assert "should be at most 160 character(s)" in errors_on(changeset).email
end
@ -150,21 +159,21 @@ defmodule Lokal.AccountsTest do
%{email: email} = user_fixture()
{:error, changeset} =
Accounts.apply_user_email(user, valid_user_password(), %{email: email})
Accounts.apply_user_email(user, valid_user_password(), %{"email" => email})
assert "has already been taken" in errors_on(changeset).email
end
test "validates current password", %{user: user} do
{:error, changeset} =
Accounts.apply_user_email(user, "invalid", %{email: unique_user_email()})
Accounts.apply_user_email(user, "invalid", %{"email" => unique_user_email()})
assert %{current_password: ["is not valid"]} = errors_on(changeset)
end
test "applies the email without persisting it", %{user: user} do
email = unique_user_email()
{:ok, user} = Accounts.apply_user_email(user, valid_user_password(), %{email: email})
{:ok, user} = Accounts.apply_user_email(user, valid_user_password(), %{"email" => email})
assert user.email == email
assert Accounts.get_user!(user.id).email != email
end
@ -234,7 +243,7 @@ defmodule Lokal.AccountsTest do
describe "change_user_password/2" do
test "returns a user changeset" do
assert %Ecto.Changeset{} = changeset = Accounts.change_user_password(%User{})
assert %Changeset{} = changeset = Accounts.change_user_password(%User{})
assert changeset.required == [:password]
end
@ -258,8 +267,8 @@ defmodule Lokal.AccountsTest do
test "validates password", %{user: user} do
{:error, changeset} =
Accounts.update_user_password(user, valid_user_password(), %{
password: "not valid",
password_confirmation: "another"
"password" => "not valid",
"password_confirmation" => "another"
})
assert %{
@ -272,14 +281,14 @@ defmodule Lokal.AccountsTest do
too_long = String.duplicate("db", 100)
{:error, changeset} =
Accounts.update_user_password(user, valid_user_password(), %{password: too_long})
Accounts.update_user_password(user, valid_user_password(), %{"password" => too_long})
assert "should be at most 80 character(s)" in errors_on(changeset).password
end
test "validates current password", %{user: user} do
{:error, changeset} =
Accounts.update_user_password(user, "invalid", %{password: valid_user_password()})
Accounts.update_user_password(user, "invalid", %{"password" => valid_user_password()})
assert %{current_password: ["is not valid"]} = errors_on(changeset)
end
@ -287,7 +296,7 @@ defmodule Lokal.AccountsTest do
test "updates the password", %{user: user} do
{:ok, user} =
Accounts.update_user_password(user, valid_user_password(), %{
password: "new valid password"
"password" => "new valid password"
})
assert is_nil(user.password)
@ -299,7 +308,7 @@ defmodule Lokal.AccountsTest do
{:ok, _} =
Accounts.update_user_password(user, valid_user_password(), %{
password: "new valid password"
"password" => "new valid password"
})
refute Repo.get_by(UserToken, user_id: user.id)
@ -467,8 +476,8 @@ defmodule Lokal.AccountsTest do
test "validates password", %{user: user} do
{:error, changeset} =
Accounts.reset_user_password(user, %{
password: "not valid",
password_confirmation: "another"
"password" => "not valid",
"password_confirmation" => "another"
})
assert %{
@ -479,19 +488,21 @@ defmodule Lokal.AccountsTest do
test "validates maximum values for password for security", %{user: user} do
too_long = String.duplicate("db", 100)
{:error, changeset} = Accounts.reset_user_password(user, %{password: too_long})
{:error, changeset} = Accounts.reset_user_password(user, %{"password" => too_long})
assert "should be at most 80 character(s)" in errors_on(changeset).password
end
test "updates the password", %{user: user} do
{:ok, updated_user} = Accounts.reset_user_password(user, %{password: "new valid password"})
{:ok, updated_user} =
Accounts.reset_user_password(user, %{"password" => "new valid password"})
assert is_nil(updated_user.password)
assert Accounts.get_user_by_email_and_password(user.email, "new valid password")
end
test "deletes all tokens for the given user", %{user: user} do
_ = Accounts.generate_user_session_token(user)
{:ok, _} = Accounts.reset_user_password(user, %{password: "new valid password"})
{:ok, _} = Accounts.reset_user_password(user, %{"password" => "new valid password"})
refute Repo.get_by(UserToken, user_id: user.id)
end
end

View File

@ -0,0 +1,76 @@
defmodule Lokal.InvitesTest do
@moduledoc """
This module tests the Invites context
"""
use Lokal.DataCase
alias Lokal.{Invites, Invites.Invite}
alias Ecto.Changeset
@moduletag :invites_test
@valid_attrs %{
"name" => "some name",
"token" => "some token"
}
@update_attrs %{
"name" => "some updated name",
"token" => "some updated token"
}
@invalid_attrs %{
"name" => nil,
"token" => nil
}
describe "invites" do
setup do
current_user = admin_fixture()
{:ok, invite} = Invites.create_invite(current_user, @valid_attrs)
[invite: invite, current_user: current_user]
end
test "list_invites/0 returns all invites", %{invite: invite, current_user: current_user} do
assert Invites.list_invites(current_user) == [invite]
end
test "get_invite!/1 returns the invite with given id",
%{invite: invite, current_user: current_user} do
assert Invites.get_invite!(invite.id, current_user) == invite
end
test "create_invite/1 with valid data creates a invite",
%{current_user: current_user} do
assert {:ok, %Invite{} = invite} = Invites.create_invite(current_user, @valid_attrs)
assert invite.name == "some name"
end
test "create_invite/1 with invalid data returns error changeset",
%{current_user: current_user} do
assert {:error, %Changeset{}} = Invites.create_invite(current_user, @invalid_attrs)
end
test "update_invite/2 with valid data updates the invite",
%{invite: invite, current_user: current_user} do
assert {:ok, %Invite{} = new_invite} =
Invites.update_invite(invite, @update_attrs, current_user)
assert new_invite.name == "some updated name"
assert new_invite.token == new_invite.token
end
test "update_invite/2 with invalid data returns error changeset",
%{invite: invite, current_user: current_user} do
assert {:error, %Changeset{}} = Invites.update_invite(invite, @invalid_attrs, current_user)
assert invite == Invites.get_invite!(invite.id, current_user)
end
test "delete_invite/1 deletes the invite", %{invite: invite, current_user: current_user} do
assert {:ok, %Invite{}} = Invites.delete_invite(invite, current_user)
assert_raise Ecto.NoResultsError, fn -> Invites.get_invite!(invite.id, current_user) end
end
test "change_invite/1 returns a invite changeset", %{invite: invite} do
assert %Changeset{} = Invites.change_invite(invite)
end
end
end

View File

@ -0,0 +1,14 @@
defmodule LokalWeb.HomeControllerTest do
@moduledoc """
Tests the home page
"""
use LokalWeb.ConnCase
@moduletag :home_controller_test
test "GET /", %{conn: conn} do
conn = get(conn, "/")
assert html_response(conn, 200) =~ "Welcome to Lokal"
end
end

View File

@ -1,10 +1,14 @@
defmodule LokalWeb.UserAuthTest do
use LokalWeb.ConnCase, async: true
@moduledoc """
Tests user auth
"""
use LokalWeb.ConnCase, async: true
import LokalWeb.Gettext
alias Lokal.Accounts
alias LokalWeb.UserAuth
import Lokal.AccountsFixtures
@moduletag :user_auth_test
@remember_me_cookie "_lokal_web_user_remember_me"
setup %{conn: conn} do
@ -13,30 +17,33 @@ defmodule LokalWeb.UserAuthTest do
|> Map.replace!(:secret_key_base, LokalWeb.Endpoint.config(:secret_key_base))
|> init_test_session(%{})
%{user: user_fixture(), conn: conn}
[current_user: user_fixture() |> confirm_user(), conn: conn]
end
describe "log_in_user/3" do
test "stores the user token in the session", %{conn: conn, user: user} do
conn = UserAuth.log_in_user(conn, user)
test "stores the user token in the session", %{conn: conn, current_user: current_user} do
conn = UserAuth.log_in_user(conn, current_user)
assert token = get_session(conn, :user_token)
assert get_session(conn, :live_socket_id) == "users_sessions:#{Base.url_encode64(token)}"
assert redirected_to(conn) == "/"
assert Accounts.get_user_by_session_token(token)
end
test "clears everything previously stored in the session", %{conn: conn, user: user} do
conn = conn |> put_session(:to_be_removed, "value") |> UserAuth.log_in_user(user)
test "clears everything previously stored in the session",
%{conn: conn, current_user: current_user} do
conn = conn |> put_session(:to_be_removed, "value") |> UserAuth.log_in_user(current_user)
refute get_session(conn, :to_be_removed)
end
test "redirects to the configured path", %{conn: conn, user: user} do
conn = conn |> put_session(:user_return_to, "/hello") |> UserAuth.log_in_user(user)
test "redirects to the configured path", %{conn: conn, current_user: current_user} do
conn = conn |> put_session(:user_return_to, "/hello") |> UserAuth.log_in_user(current_user)
assert redirected_to(conn) == "/hello"
end
test "writes a cookie if remember_me is configured", %{conn: conn, user: user} do
conn = conn |> fetch_cookies() |> UserAuth.log_in_user(user, %{"remember_me" => "true"})
test "writes a cookie if remember_me is configured", %{conn: conn, current_user: current_user} do
conn =
conn |> fetch_cookies() |> UserAuth.log_in_user(current_user, %{"remember_me" => "true"})
assert get_session(conn, :user_token) == conn.cookies[@remember_me_cookie]
assert %{value: signed_token, max_age: max_age} = conn.resp_cookies[@remember_me_cookie]
@ -46,8 +53,8 @@ defmodule LokalWeb.UserAuthTest do
end
describe "logout_user/1" do
test "erases session and cookies", %{conn: conn, user: user} do
user_token = Accounts.generate_user_session_token(user)
test "erases session and cookies", %{conn: conn, current_user: current_user} do
user_token = Accounts.generate_user_session_token(current_user)
conn =
conn
@ -86,15 +93,15 @@ defmodule LokalWeb.UserAuthTest do
end
describe "fetch_current_user/2" do
test "authenticates user from session", %{conn: conn, user: user} do
user_token = Accounts.generate_user_session_token(user)
test "authenticates user from session", %{conn: conn, current_user: current_user} do
user_token = Accounts.generate_user_session_token(current_user)
conn = conn |> put_session(:user_token, user_token) |> UserAuth.fetch_current_user([])
assert conn.assigns.current_user.id == user.id
assert conn.assigns.current_user.id == current_user.id
end
test "authenticates user from cookies", %{conn: conn, user: user} do
test "authenticates user from cookies", %{conn: conn, current_user: current_user} do
logged_in_conn =
conn |> fetch_cookies() |> UserAuth.log_in_user(user, %{"remember_me" => "true"})
conn |> fetch_cookies() |> UserAuth.log_in_user(current_user, %{"remember_me" => "true"})
user_token = logged_in_conn.cookies[@remember_me_cookie]
%{value: signed_token} = logged_in_conn.resp_cookies[@remember_me_cookie]
@ -105,11 +112,11 @@ defmodule LokalWeb.UserAuthTest do
|> UserAuth.fetch_current_user([])
assert get_session(conn, :user_token) == user_token
assert conn.assigns.current_user.id == user.id
assert conn.assigns.current_user.id == current_user.id
end
test "does not authenticate if data is missing", %{conn: conn, user: user} do
_ = Accounts.generate_user_session_token(user)
test "does not authenticate if data is missing", %{conn: conn, current_user: current_user} do
_ = Accounts.generate_user_session_token(current_user)
conn = UserAuth.fetch_current_user(conn, [])
refute get_session(conn, :user_token)
refute conn.assigns.current_user
@ -117,8 +124,12 @@ defmodule LokalWeb.UserAuthTest do
end
describe "redirect_if_user_is_authenticated/2" do
test "redirects if user is authenticated", %{conn: conn, user: user} do
conn = conn |> assign(:current_user, user) |> UserAuth.redirect_if_user_is_authenticated([])
test "redirects if user is authenticated", %{conn: conn, current_user: current_user} do
conn =
conn
|> assign(:current_user, current_user)
|> UserAuth.redirect_if_user_is_authenticated([])
assert conn.halted
assert redirected_to(conn) == "/"
end
@ -135,7 +146,9 @@ defmodule LokalWeb.UserAuthTest do
conn = conn |> fetch_flash() |> UserAuth.require_authenticated_user([])
assert conn.halted
assert redirected_to(conn) == Routes.user_session_path(conn, :new)
assert get_flash(conn, :error) == "You must log in to access this page."
assert get_flash(conn, :error) ==
dgettext("errors", "You must confirm your account and log in to access this page.")
end
test "stores the path to redirect to on GET", %{conn: conn} do
@ -156,7 +169,7 @@ defmodule LokalWeb.UserAuthTest do
assert get_session(halted_conn, :user_return_to) == "/foo?bar=baz"
halted_conn =
%{conn | path_info: ["foo"], query_string: "bar", method: "POST"}
%{conn | path_info: ["/foo?bar"], method: "POST"}
|> fetch_flash()
|> UserAuth.require_authenticated_user([])
@ -164,8 +177,10 @@ defmodule LokalWeb.UserAuthTest do
refute get_session(halted_conn, :user_return_to)
end
test "does not redirect if user is authenticated", %{conn: conn, user: user} do
conn = conn |> assign(:current_user, user) |> UserAuth.require_authenticated_user([])
test "does not redirect if user is authenticated", %{conn: conn, current_user: current_user} do
conn =
conn |> assign(:current_user, current_user) |> UserAuth.require_authenticated_user([])
refute conn.halted
refute conn.status
end

View File

@ -1,9 +1,14 @@
defmodule LokalWeb.UserConfirmationControllerTest do
use LokalWeb.ConnCase, async: true
@moduledoc """
Tests user confirmation
"""
use LokalWeb.ConnCase, async: true
import LokalWeb.Gettext
alias Lokal.Accounts
alias Lokal.Repo
import Lokal.AccountsFixtures
@moduletag :user_confirmation_controller_test
setup do
%{user: user_fixture()}
@ -13,7 +18,7 @@ defmodule LokalWeb.UserConfirmationControllerTest do
test "renders the confirmation page", %{conn: conn} do
conn = get(conn, Routes.user_confirmation_path(conn, :new))
response = html_response(conn, 200)
assert response =~ "Resend confirmation instructions"
assert response =~ dgettext("actions", "Resend confirmation instructions")
end
end
@ -26,7 +31,14 @@ defmodule LokalWeb.UserConfirmationControllerTest do
})
assert redirected_to(conn) == "/"
assert get_flash(conn, :info) =~ "If your email is in our system"
assert get_flash(conn, :info) =~
dgettext(
"prompts",
"If your email is in our system and it has not been confirmed yet, " <>
"you will receive an email with instructions shortly."
)
assert Repo.get_by!(Accounts.UserToken, user_id: user.id).context == "confirm"
end
@ -39,8 +51,13 @@ defmodule LokalWeb.UserConfirmationControllerTest do
})
assert redirected_to(conn) == "/"
assert get_flash(conn, :info) =~ "If your email is in our system"
refute Repo.get_by(Accounts.UserToken, user_id: user.id)
assert get_flash(conn, :info) =~
dgettext(
"prompts",
"If your email is in our system and it has not been confirmed yet, " <>
"you will receive an email with instructions shortly."
)
end
test "does not send confirmation token if email is invalid", %{conn: conn} do
@ -50,7 +67,14 @@ defmodule LokalWeb.UserConfirmationControllerTest do
})
assert redirected_to(conn) == "/"
assert get_flash(conn, :info) =~ "If your email is in our system"
assert get_flash(conn, :info) =~
dgettext(
"prompts",
"If your email is in our system and it has not been confirmed yet, " <>
"you will receive an email with instructions shortly."
)
assert Repo.all(Accounts.UserToken) == []
end
end
@ -64,7 +88,10 @@ defmodule LokalWeb.UserConfirmationControllerTest do
conn = get(conn, Routes.user_confirmation_path(conn, :confirm, token))
assert redirected_to(conn) == "/"
assert get_flash(conn, :info) =~ "User confirmed successfully"
assert get_flash(conn, :info) =~
dgettext("prompts", "%{email} confirmed successfully", email: user.email)
assert Accounts.get_user!(user.id).confirmed_at
refute get_session(conn, :user_token)
assert Repo.all(Accounts.UserToken) == []
@ -72,7 +99,9 @@ defmodule LokalWeb.UserConfirmationControllerTest do
# When not logged in
conn = get(conn, Routes.user_confirmation_path(conn, :confirm, token))
assert redirected_to(conn) == "/"
assert get_flash(conn, :error) =~ "User confirmation link is invalid or it has expired"
assert get_flash(conn, :error) =~
dgettext("errors", "User confirmation link is invalid or it has expired")
# When logged in
conn =
@ -87,7 +116,10 @@ defmodule LokalWeb.UserConfirmationControllerTest do
test "does not confirm email with invalid token", %{conn: conn, user: user} do
conn = get(conn, Routes.user_confirmation_path(conn, :confirm, "oops"))
assert redirected_to(conn) == "/"
assert get_flash(conn, :error) =~ "User confirmation link is invalid or it has expired"
assert get_flash(conn, :error) =~
dgettext("errors", "User confirmation link is invalid or it has expired")
refute Accounts.get_user!(user.id).confirmed_at
end
end

View File

@ -1,15 +1,19 @@
defmodule LokalWeb.UserRegistrationControllerTest do
use LokalWeb.ConnCase, async: true
@moduledoc """
Tests user registration
"""
import Lokal.AccountsFixtures
use LokalWeb.ConnCase, async: true
import LokalWeb.Gettext
@moduletag :user_registration_controller_test
describe "GET /users/register" do
test "renders registration page", %{conn: conn} do
conn = get(conn, Routes.user_registration_path(conn, :new))
response = html_response(conn, 200)
assert response =~ "Register"
assert response =~ "Log in</a>"
assert response =~ "Register</a>"
assert response =~ dgettext("actions", "Register")
assert response =~ dgettext("actions", "Log in")
end
test "redirects if already logged in", %{conn: conn} do
@ -28,15 +32,17 @@ defmodule LokalWeb.UserRegistrationControllerTest do
"user" => valid_user_attributes(email: email)
})
assert get_session(conn, :user_token)
assert get_session(conn, :phoenix_flash) == %{
"info" => dgettext("prompts", "Please check your email to verify your account")
}
assert redirected_to(conn) =~ "/"
# Now do a logged in request and assert on the menu
conn = get(conn, "/")
response = html_response(conn, 200)
# user's email is recorded as admin
assert response =~ email
assert response =~ "Settings</a>"
assert response =~ "Log out</a>"
end
test "render errors for invalid data", %{conn: conn} do
@ -46,7 +52,7 @@ defmodule LokalWeb.UserRegistrationControllerTest do
})
response = html_response(conn, 200)
assert response =~ "Register"
assert response =~ gettext("Register")
assert response =~ "must have the @ sign and no spaces"
assert response =~ "should be at least 12 character"
end

View File

@ -1,9 +1,13 @@
defmodule LokalWeb.UserResetPasswordControllerTest do
use LokalWeb.ConnCase, async: true
@moduledoc """
Tests the user reset password controller
"""
alias Lokal.Accounts
alias Lokal.Repo
import Lokal.AccountsFixtures
use LokalWeb.ConnCase, async: true
import LokalWeb.Gettext
alias Lokal.{Accounts, Repo}
@moduletag :user_reset_password_controller_test
setup do
%{user: user_fixture()}
@ -13,7 +17,7 @@ defmodule LokalWeb.UserResetPasswordControllerTest do
test "renders the reset password page", %{conn: conn} do
conn = get(conn, Routes.user_reset_password_path(conn, :new))
response = html_response(conn, 200)
assert response =~ "Forgot your password?"
assert response =~ dgettext("actions", "Forgot your password?")
end
end
@ -26,7 +30,13 @@ defmodule LokalWeb.UserResetPasswordControllerTest do
})
assert redirected_to(conn) == "/"
assert get_flash(conn, :info) =~ "If your email is in our system"
assert get_flash(conn, :info) =~
dgettext(
"prompts",
"If your email is in our system, you will receive instructions to reset your password shortly."
)
assert Repo.get_by!(Accounts.UserToken, user_id: user.id).context == "reset_password"
end
@ -37,7 +47,13 @@ defmodule LokalWeb.UserResetPasswordControllerTest do
})
assert redirected_to(conn) == "/"
assert get_flash(conn, :info) =~ "If your email is in our system"
assert get_flash(conn, :info) =~
dgettext(
"prompts",
"If your email is in our system, you will receive instructions to reset your password shortly."
)
assert Repo.all(Accounts.UserToken) == []
end
end
@ -54,13 +70,15 @@ defmodule LokalWeb.UserResetPasswordControllerTest do
test "renders reset password", %{conn: conn, token: token} do
conn = get(conn, Routes.user_reset_password_path(conn, :edit, token))
assert html_response(conn, 200) =~ "Reset password"
assert html_response(conn, 200) =~ dgettext("actions", "Reset password")
end
test "does not render reset password with invalid token", %{conn: conn} do
conn = get(conn, Routes.user_reset_password_path(conn, :edit, "oops"))
assert redirected_to(conn) == "/"
assert get_flash(conn, :error) =~ "Reset password link is invalid or it has expired"
assert get_flash(conn, :error) =~
dgettext("errors", "Reset password link is invalid or it has expired")
end
end
@ -85,7 +103,7 @@ defmodule LokalWeb.UserResetPasswordControllerTest do
assert redirected_to(conn) == Routes.user_session_path(conn, :new)
refute get_session(conn, :user_token)
assert get_flash(conn, :info) =~ "Password reset successfully"
assert get_flash(conn, :info) =~ dgettext("prompts", "Password reset successfully")
assert Accounts.get_user_by_email_and_password(user.email, "new valid password")
end
@ -99,15 +117,17 @@ defmodule LokalWeb.UserResetPasswordControllerTest do
})
response = html_response(conn, 200)
assert response =~ "Reset password"
assert response =~ "should be at least 12 character(s)"
assert response =~ "does not match password"
assert response =~ gettext("Reset password")
assert response =~ dgettext("errors", "should be at least 12 character(s)")
assert response =~ dgettext("errors", "does not match password")
end
test "does not reset password with invalid token", %{conn: conn} do
conn = put(conn, Routes.user_reset_password_path(conn, :update, "oops"))
assert redirected_to(conn) == "/"
assert get_flash(conn, :error) =~ "Reset password link is invalid or it has expired"
assert get_flash(conn, :error) =~
dgettext("errors", "Reset password link is invalid or it has expired")
end
end
end

View File

@ -1,31 +1,35 @@
defmodule LokalWeb.UserSessionControllerTest do
@moduledoc """
Tests the user session controller
"""
use LokalWeb.ConnCase, async: true
import LokalWeb.Gettext
import Lokal.AccountsFixtures
@moduletag :user_session_controller_test
setup do
%{user: user_fixture()}
setup %{conn: conn} do
[current_user: user_fixture() |> confirm_user(), conn: conn]
end
describe "GET /users/log_in" do
test "renders log in page", %{conn: conn} do
conn = get(conn, Routes.user_session_path(conn, :new))
response = html_response(conn, 200)
assert response =~ "Log in"
assert response =~ "Register"
assert response =~ dgettext("actions", "Log in")
end
test "redirects if already logged in", %{conn: conn, user: user} do
conn = conn |> log_in_user(user) |> get(Routes.user_session_path(conn, :new))
test "redirects if already logged in", %{conn: conn, current_user: current_user} do
conn = conn |> log_in_user(current_user) |> get(Routes.user_session_path(conn, :new))
assert redirected_to(conn) == "/"
end
end
describe "POST /users/log_in" do
test "logs the user in", %{conn: conn, user: user} do
test "logs the user in", %{conn: conn, current_user: current_user} do
conn =
post(conn, Routes.user_session_path(conn, :create), %{
"user" => %{"email" => user.email, "password" => valid_user_password()}
"user" => %{"email" => current_user.email, "password" => valid_user_password()}
})
assert get_session(conn, :user_token)
@ -34,16 +38,15 @@ defmodule LokalWeb.UserSessionControllerTest do
# Now do a logged in request and assert on the menu
conn = get(conn, "/")
response = html_response(conn, 200)
assert response =~ user.email
assert response =~ "Settings</a>"
assert response =~ "Log out</a>"
assert response =~ current_user.email
assert response =~ dgettext("prompts", "Are you sure you want to log out?")
end
test "logs the user in with remember me", %{conn: conn, user: user} do
test "logs the user in with remember me", %{conn: conn, current_user: current_user} do
conn =
post(conn, Routes.user_session_path(conn, :create), %{
"user" => %{
"email" => user.email,
"email" => current_user.email,
"password" => valid_user_password(),
"remember_me" => "true"
}
@ -53,13 +56,13 @@ defmodule LokalWeb.UserSessionControllerTest do
assert redirected_to(conn) =~ "/"
end
test "logs the user in with return to", %{conn: conn, user: user} do
test "logs the user in with return to", %{conn: conn, current_user: current_user} do
conn =
conn
|> init_test_session(user_return_to: "/foo/bar")
|> post(Routes.user_session_path(conn, :create), %{
"user" => %{
"email" => user.email,
"email" => current_user.email,
"password" => valid_user_password()
}
})
@ -67,31 +70,32 @@ defmodule LokalWeb.UserSessionControllerTest do
assert redirected_to(conn) == "/foo/bar"
end
test "emits error message with invalid credentials", %{conn: conn, user: user} do
test "emits error message with invalid credentials",
%{conn: conn, current_user: current_user} do
conn =
post(conn, Routes.user_session_path(conn, :create), %{
"user" => %{"email" => user.email, "password" => "invalid_password"}
"user" => %{"email" => current_user.email, "password" => "bad"}
})
response = html_response(conn, 200)
assert response =~ "Log in"
assert response =~ "Invalid email or password"
assert response =~ dgettext("actions", "Log in")
assert response =~ dgettext("errors", "Invalid email or password")
end
end
describe "DELETE /users/log_out" do
test "logs the user out", %{conn: conn, user: user} do
conn = conn |> log_in_user(user) |> delete(Routes.user_session_path(conn, :delete))
test "logs the user out", %{conn: conn, current_user: current_user} do
conn = conn |> log_in_user(current_user) |> delete(Routes.user_session_path(conn, :delete))
assert redirected_to(conn) == "/"
refute get_session(conn, :user_token)
assert get_flash(conn, :info) =~ "Logged out successfully"
assert get_flash(conn, :info) =~ gettext("Logged out successfully")
end
test "succeeds even if the user is not logged in", %{conn: conn} do
conn = delete(conn, Routes.user_session_path(conn, :delete))
assert redirected_to(conn) == "/"
refute get_session(conn, :user_token)
assert get_flash(conn, :info) =~ "Logged out successfully"
assert get_flash(conn, :info) =~ gettext("Logged out successfully")
end
end
end

View File

@ -1,8 +1,13 @@
defmodule LokalWeb.UserSettingsControllerTest do
use LokalWeb.ConnCase, async: true
@moduledoc """
Tests the user settings controller
"""
use LokalWeb.ConnCase, async: true
import LokalWeb.Gettext
alias Lokal.Accounts
import Lokal.AccountsFixtures
@moduletag :user_settings_controller_test
setup :register_and_log_in_user
@ -10,7 +15,7 @@ defmodule LokalWeb.UserSettingsControllerTest do
test "renders settings page", %{conn: conn} do
conn = get(conn, Routes.user_settings_path(conn, :edit))
response = html_response(conn, 200)
assert response =~ "Settings"
assert response =~ gettext("Settings")
end
test "redirects if user is not logged in" do
@ -21,7 +26,8 @@ defmodule LokalWeb.UserSettingsControllerTest do
end
describe "PUT /users/settings (change password form)" do
test "updates the user password and resets tokens", %{conn: conn, user: user} do
test "updates the user password and resets tokens",
%{conn: conn, current_user: current_user} do
new_password_conn =
put(conn, Routes.user_settings_path(conn, :update), %{
"action" => "update_password",
@ -34,8 +40,11 @@ defmodule LokalWeb.UserSettingsControllerTest do
assert redirected_to(new_password_conn) == Routes.user_settings_path(conn, :edit)
assert get_session(new_password_conn, :user_token) != get_session(conn, :user_token)
assert get_flash(new_password_conn, :info) =~ "Password updated successfully"
assert Accounts.get_user_by_email_and_password(user.email, "new valid password")
assert get_flash(new_password_conn, :info) =~
dgettext("actions", "Password updated successfully")
assert Accounts.get_user_by_email_and_password(current_user.email, "new valid password")
end
test "does not update password on invalid data", %{conn: conn} do
@ -50,10 +59,10 @@ defmodule LokalWeb.UserSettingsControllerTest do
})
response = html_response(old_password_conn, 200)
assert response =~ "Settings"
assert response =~ "should be at least 12 character(s)"
assert response =~ "does not match password"
assert response =~ "is not valid"
assert response =~ gettext("Settings")
assert response =~ dgettext("errors", "should be at least 12 character(s)")
assert response =~ dgettext("errors", "does not match password")
assert response =~ dgettext("errors", "is not valid")
assert get_session(old_password_conn, :user_token) == get_session(conn, :user_token)
end
@ -61,7 +70,7 @@ defmodule LokalWeb.UserSettingsControllerTest do
describe "PUT /users/settings (change email form)" do
@tag :capture_log
test "updates the user email", %{conn: conn, user: user} do
test "updates the user email", %{conn: conn, current_user: current_user} do
conn =
put(conn, Routes.user_settings_path(conn, :update), %{
"action" => "update_email",
@ -70,8 +79,14 @@ defmodule LokalWeb.UserSettingsControllerTest do
})
assert redirected_to(conn) == Routes.user_settings_path(conn, :edit)
assert get_flash(conn, :info) =~ "A link to confirm your email"
assert Accounts.get_user_by_email(user.email)
assert get_flash(conn, :info) =~
dgettext(
"prompts",
"A link to confirm your email change has been sent to the new address."
)
assert Accounts.get_user_by_email(current_user.email)
end
test "does not update email on invalid data", %{conn: conn} do
@ -83,41 +98,51 @@ defmodule LokalWeb.UserSettingsControllerTest do
})
response = html_response(conn, 200)
assert response =~ "Settings"
assert response =~ "must have the @ sign and no spaces"
assert response =~ "is not valid"
assert response =~ gettext("Settings")
assert response =~ dgettext("errors", "must have the @ sign and no spaces")
assert response =~ dgettext("errors", "is not valid")
end
end
describe "GET /users/settings/confirm_email/:token" do
setup %{user: user} do
setup %{current_user: current_user} do
email = unique_user_email()
token =
extract_user_token(fn url ->
Accounts.deliver_update_email_instructions(%{user | email: email}, user.email, url)
Accounts.deliver_update_email_instructions(
%{current_user | email: email},
current_user.email,
url
)
end)
%{token: token, email: email}
end
test "updates the user email once", %{conn: conn, user: user, token: token, email: email} do
test "updates the user email once",
%{conn: conn, current_user: current_user, token: token, email: email} do
conn = get(conn, Routes.user_settings_path(conn, :confirm_email, token))
assert redirected_to(conn) == Routes.user_settings_path(conn, :edit)
assert get_flash(conn, :info) =~ "Email changed successfully"
refute Accounts.get_user_by_email(user.email)
assert get_flash(conn, :info) =~ dgettext("prompts", "Email changed successfully")
refute Accounts.get_user_by_email(current_user.email)
assert Accounts.get_user_by_email(email)
conn = get(conn, Routes.user_settings_path(conn, :confirm_email, token))
assert redirected_to(conn) == Routes.user_settings_path(conn, :edit)
assert get_flash(conn, :error) =~ "Email change link is invalid or it has expired"
assert get_flash(conn, :error) =~
dgettext("errors", "Email change link is invalid or it has expired")
end
test "does not update email with invalid token", %{conn: conn, user: user} do
test "does not update email with invalid token", %{conn: conn, current_user: current_user} do
conn = get(conn, Routes.user_settings_path(conn, :confirm_email, "oops"))
assert redirected_to(conn) == Routes.user_settings_path(conn, :edit)
assert get_flash(conn, :error) =~ "Email change link is invalid or it has expired"
assert Accounts.get_user_by_email(user.email)
assert get_flash(conn, :error) =~
dgettext("errors", "Email change link is invalid or it has expired")
assert Accounts.get_user_by_email(current_user.email)
end
test "redirects if user is not logged in", %{token: token} do

View File

@ -0,0 +1,85 @@
defmodule LokalWeb.InviteLiveTest do
@moduledoc """
Tests the invite liveview
"""
use LokalWeb.ConnCase
import Phoenix.LiveViewTest
import LokalWeb.Gettext
alias Lokal.Invites
@moduletag :invite_live_test
@create_attrs %{"name" => "some name"}
@update_attrs %{"name" => "some updated name"}
# @invalid_attrs %{"name" => nil}
describe "Index" do
setup [:register_and_log_in_user]
setup %{current_user: current_user} do
{:ok, invite} = Invites.create_invite(current_user, @create_attrs)
%{invite: invite, current_user: current_user}
end
test "lists all invites", %{conn: conn, invite: invite} do
{:ok, _index_live, html} = live(conn, Routes.invite_index_path(conn, :index))
assert html =~ gettext("Invites")
assert html =~ invite.name
end
test "saves new invite", %{conn: conn} do
{:ok, index_live, _html} = live(conn, Routes.invite_index_path(conn, :index))
assert index_live |> element("a", dgettext("actions", "Create Invite")) |> render_click() =~
gettext("New Invite")
assert_patch(index_live, Routes.invite_index_path(conn, :new))
# assert index_live
# |> form("#invite-form", invite: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
{:ok, _, html} =
index_live
|> form("#invite-form", invite: @create_attrs)
|> render_submit()
|> follow_redirect(conn, Routes.invite_index_path(conn, :index))
assert html =~ dgettext("prompts", "%{name} created successfully", name: "some name")
assert html =~ "some name"
end
test "updates invite in listing", %{conn: conn, invite: invite} do
{:ok, index_live, _html} = live(conn, Routes.invite_index_path(conn, :index))
assert index_live |> element("[data-qa=\"edit-#{invite.id}\"]") |> render_click() =~
gettext("Edit Invite")
assert_patch(index_live, Routes.invite_index_path(conn, :edit, invite))
# assert index_live
# |> form("#invite-form", invite: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
{:ok, _, html} =
index_live
|> form("#invite-form", invite: @update_attrs)
|> render_submit()
|> follow_redirect(conn, Routes.invite_index_path(conn, :index))
assert html =~
dgettext("prompts", "%{name} updated successfully", name: "some updated name")
assert html =~ "some updated name"
end
test "deletes invite in listing", %{conn: conn, invite: invite} do
{:ok, index_live, _html} = live(conn, Routes.invite_index_path(conn, :index))
assert index_live |> element("[data-qa=\"delete-#{invite.id}\"]") |> render_click()
refute has_element?(index_live, "#invite-#{invite.id}")
end
end
end

View File

@ -1,14 +1,23 @@
defmodule LokalWeb.ErrorViewTest do
@moduledoc """
Tests the error view
"""
use LokalWeb.ConnCase, async: true
import LokalWeb.Gettext
@moduletag :error_view_test
# Bring render/3 and render_to_string/3 for testing custom views
import Phoenix.View
test "renders 404.html" do
assert render_to_string(LokalWeb.ErrorView, "404.html", []) == "Not Found"
assert render_to_string(LokalWeb.ErrorView, "404.html", []) =~
dgettext("errors", "Not found")
end
test "renders 500.html" do
assert render_to_string(LokalWeb.ErrorView, "500.html", []) == "Internal Server Error"
assert render_to_string(LokalWeb.ErrorView, "500.html", []) =~
dgettext("errors", "Internal Server Error")
end
end

View File

@ -16,14 +16,16 @@ defmodule LokalWeb.ConnCase do
"""
use ExUnit.CaseTemplate
import Lokal.Fixtures
alias Lokal.{Accounts, Accounts.User, Repo}
alias Ecto.Adapters.SQL.Sandbox
alias Lokal.{Accounts, Repo}
using do
quote do
# Import conveniences for testing with connections
import Plug.Conn
import Phoenix.ConnTest
import Lokal.Fixtures
import LokalWeb.ConnCase
alias LokalWeb.Router.Helpers, as: Routes
@ -47,12 +49,17 @@ defmodule LokalWeb.ConnCase do
It stores an updated connection and a registered user in the
test context.
"""
@spec register_and_log_in_user(%{conn: Plug.Conn.t()}) ::
%{conn: Plug.Conn.t(), current_user: User.t()}
def register_and_log_in_user(%{conn: conn}) do
user = Lokal.AccountsFixtures.user_fixture()
current_user = user_fixture() |> confirm_user()
%{conn: log_in_user(conn, current_user), current_user: current_user}
end
@spec confirm_user(User.t()) :: User.t()
def confirm_user(user) do
{:ok, %{user: user}} = user |> Accounts.confirm_user_multi() |> Repo.transaction()
%{conn: log_in_user(conn, user), user: user}
user
end
@doc """

View File

@ -25,6 +25,7 @@ defmodule Lokal.DataCase do
import Ecto.Changeset
import Ecto.Query
import Lokal.DataCase
import Lokal.Fixtures
end
end

60
test/support/fixtures.ex Normal file
View File

@ -0,0 +1,60 @@
defmodule Lokal.Fixtures do
@moduledoc """
This module defines test helpers for creating entities
"""
alias Lokal.{Accounts, Accounts.User, Email}
def unique_user_email, do: "user#{System.unique_integer()}@example.com"
def valid_user_password, do: "hello world!"
@spec user_fixture() :: Accounts.User.t()
@spec user_fixture(attrs :: map()) :: Accounts.User.t()
def user_fixture(attrs \\ %{}) do
attrs
|> Enum.into(%{
"email" => unique_user_email(),
"password" => valid_user_password()
})
|> Accounts.register_user()
|> unwrap_ok_tuple()
end
@spec admin_fixture() :: Accounts.User.t()
@spec admin_fixture(attrs :: map()) :: Accounts.User.t()
def admin_fixture(attrs \\ %{}) do
attrs
|> Enum.into(%{
"email" => unique_user_email(),
"password" => valid_user_password(),
"role" => "admin"
})
|> Accounts.register_user()
|> unwrap_ok_tuple()
end
def extract_user_token(fun) do
%{args: %{attrs: attrs, email: email_key, user_id: user_id}} = fun.(&"[TOKEN]#{&1}[TOKEN]")
# convert atoms to string keys
attrs = attrs |> Map.new(fn {atom_key, value} -> {atom_key |> Atom.to_string(), value} end)
email =
email_key
|> Atom.to_string()
|> Email.generate_email(Accounts.get_user!(user_id), attrs)
[_, html_token | _] = email.html_body |> String.split("[TOKEN]")
[_, text_token | _] = email.text_body |> String.split("[TOKEN]")
^text_token = html_token
end
def valid_user_attributes(attrs \\ %{}) do
Enum.into(attrs, %{
email: unique_user_email(),
password: valid_user_password()
})
end
defp unwrap_ok_tuple({:ok, value}), do: value
end

View File

@ -1,31 +0,0 @@
defmodule Lokal.AccountsFixtures do
@moduledoc """
This module defines test helpers for creating
entities via the `Lokal.Accounts` context.
"""
def unique_user_email, do: "user#{System.unique_integer()}@example.com"
def valid_user_password, do: "hello world!"
def valid_user_attributes(attrs \\ %{}) do
Enum.into(attrs, %{
email: unique_user_email(),
password: valid_user_password()
})
end
def user_fixture(attrs \\ %{}) do
{:ok, user} =
attrs
|> valid_user_attributes()
|> Lokal.Accounts.register_user()
user
end
def extract_user_token(fun) do
{:ok, captured} = fun.(&"[TOKEN]#{&1}[TOKEN]")
[_, token, _] = String.split(captured.body, "[TOKEN]")
token
end
end