improve invites, record usage

This commit is contained in:
2023-02-04 16:46:37 -05:00
parent 47dab6490d
commit 2c0a4dd7ca
46 changed files with 988 additions and 725 deletions

View File

@ -0,0 +1,176 @@
defmodule Cannery.InvitesTest do
@moduledoc """
This module tests the Cannery.Accounts.Invites context
"""
use Cannery.DataCase
alias Cannery.Accounts
alias Cannery.Accounts.{Invite, Invites}
alias Ecto.Changeset
@moduletag :invites_test
@valid_attrs %{
"name" => "some name"
}
@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 "valid_invite_token? returns for valid and invalid invite tokens",
%{invite: %{token: token}} do
refute Invites.valid_invite_token?(nil)
refute Invites.valid_invite_token?("")
assert Invites.valid_invite_token?(token)
end
test "valid_invite_token? does not return true for a disabled invite by token",
%{invite: %{token: token} = invite, current_user: current_user} do
assert Invites.valid_invite_token?(token)
{:ok, _invite} = Invites.update_invite(invite, %{uses_left: 1}, current_user)
{:ok, _invite} = Invites.use_invite(token)
refute Invites.valid_invite_token?(token)
end
test "get_use_count/2 returns the correct invite usage",
%{invite: %{token: token} = invite, current_user: current_user} do
assert 0 == Invites.get_use_count(invite, current_user)
assert {:ok, _user} =
Accounts.register_user(
%{"email" => unique_user_email(), "password" => valid_user_password()},
token
)
assert 1 == Invites.get_use_count(invite, current_user)
assert {:ok, _user} =
Accounts.register_user(
%{"email" => unique_user_email(), "password" => valid_user_password()},
token
)
assert 2 == Invites.get_use_count(invite, current_user)
end
test "use_invite/1 successfully uses an unlimited invite",
%{invite: %{token: token} = invite, current_user: current_user} do
{:ok, invite} = Invites.update_invite(invite, %{uses_left: nil}, current_user)
assert {:ok, ^invite} = Invites.use_invite(token)
assert {:ok, ^invite} = Invites.use_invite(token)
assert {:ok, ^invite} = Invites.use_invite(token)
end
test "use_invite/1 successfully decrements an invite",
%{invite: %{token: token} = invite, current_user: current_user} do
{:ok, _invite} = Invites.update_invite(invite, %{uses_left: 10}, current_user)
assert {:ok, %{uses_left: 9}} = Invites.use_invite(token)
assert {:ok, %{uses_left: 8}} = Invites.use_invite(token)
assert {:ok, %{uses_left: 7}} = Invites.use_invite(token)
end
test "use_invite/1 successfully disactivates an invite",
%{invite: %{token: token} = invite, current_user: current_user} do
{:ok, _invite} = Invites.update_invite(invite, %{uses_left: 1}, current_user)
assert {:ok, %{uses_left: 0, disabled_at: disabled_at}} = Invites.use_invite(token)
assert not is_nil(disabled_at)
end
test "use_invite/1 does not work on disactivated invite",
%{invite: %{token: token} = invite, current_user: current_user} do
{:ok, _invite} = Invites.update_invite(invite, %{uses_left: 1}, current_user)
{:ok, _invite} = Invites.use_invite(token)
assert {:error, :invalid_token} = Invites.use_invite(token)
end
test "create_invite/1 with valid data creates an unlimited invite",
%{current_user: current_user} do
assert {:ok, %Invite{} = invite} =
Invites.create_invite(current_user, %{
"name" => "some name"
})
assert invite.name == "some name"
end
test "create_invite/1 with valid data creates a limited invite",
%{current_user: current_user} do
assert {:ok, %Invite{} = invite} =
Invites.create_invite(current_user, %{
"name" => "some name",
"uses_left" => 10
})
assert invite.name == "some name"
assert invite.uses_left == 10
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 can set an invite to be limited",
%{invite: invite, current_user: current_user} do
assert {:ok, %Invite{} = new_invite} =
Invites.update_invite(
invite,
%{"name" => "some updated name", "uses_left" => 5},
current_user
)
assert new_invite.name == "some updated name"
assert new_invite.uses_left == 5
end
test "update_invite/2 can set an invite to be unlimited",
%{invite: invite, current_user: current_user} do
{:ok, invite} = Invites.update_invite(invite, %{"uses_left" => 5}, current_user)
assert {:ok, %Invite{} = new_invite} =
Invites.update_invite(
invite,
%{"name" => "some updated name", "uses_left" => nil},
current_user
)
assert new_invite.name == "some updated name"
assert new_invite.uses_left |> is_nil()
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 "delete_invite!/1 deletes the invite", %{invite: invite, current_user: current_user} do
assert %Invite{} = Invites.delete_invite!(invite, current_user)
assert_raise Ecto.NoResultsError, fn -> Invites.get_invite!(invite.id, current_user) end
end
end
end

View File

@ -5,7 +5,7 @@ defmodule Cannery.AccountsTest do
use Cannery.DataCase
alias Cannery.Accounts
alias Cannery.Accounts.{User, UserToken}
alias Cannery.Accounts.{Invites, User, UserToken}
alias Ecto.Changeset
@moduletag :accounts_test
@ -102,6 +102,17 @@ defmodule Cannery.AccountsTest do
assert is_nil(user.confirmed_at)
assert is_nil(user.password)
end
test "records used invite during registration" do
{:ok, %{id: invite_id, token: token}} =
admin_fixture() |> Invites.create_invite(%{"name" => "my invite"})
assert {:ok, %{invite_id: ^invite_id}} =
Accounts.register_user(
%{"email" => unique_user_email(), "password" => valid_user_password()},
token
)
end
end
describe "change_user_registration/2" do
@ -305,9 +316,9 @@ defmodule Cannery.AccountsTest do
end
test "deletes all tokens for the given user", %{user: user} do
_token = Accounts.generate_user_session_token(user)
_session_token = Accounts.generate_user_session_token(user)
{:ok, _user} =
{:ok, _} =
Accounts.update_user_password(user, valid_user_password(), %{
"password" => "new valid password"
})
@ -502,7 +513,7 @@ defmodule Cannery.AccountsTest do
end
test "deletes all tokens for the given user", %{user: user} do
_token = Accounts.generate_user_session_token(user)
_session_token = Accounts.generate_user_session_token(user)
{:ok, _user} = Accounts.reset_user_password(user, %{"password" => "new valid password"})
refute Repo.get_by(UserToken, user_id: user.id)
end

View File

@ -1,72 +0,0 @@
defmodule Cannery.InvitesTest do
@moduledoc """
This module tests the Invites context
"""
use Cannery.DataCase
alias Cannery.{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
end
end

View File

@ -8,14 +8,7 @@ defmodule CanneryWeb.ExportControllerTest do
@moduletag :export_controller_test
setup %{conn: conn} do
current_user = user_fixture() |> confirm_user()
[
current_user: current_user,
conn: conn |> log_in_user(current_user)
]
end
setup [:register_and_log_in_user]
defp add_data(%{current_user: current_user}) do
ammo_type = ammo_type_fixture(current_user)
@ -124,7 +117,9 @@ defmodule CanneryWeb.ExportControllerTest do
"email" => current_user.email,
"id" => current_user.id,
"locale" => current_user.locale,
"role" => to_string(current_user.role)
"role" => to_string(current_user.role),
"inserted_at" => current_user.inserted_at |> NaiveDateTime.to_iso8601(),
"updated_at" => current_user.updated_at |> NaiveDateTime.to_iso8601()
}
json_resp = conn |> json_response(200)

View File

@ -6,7 +6,7 @@ defmodule CanneryWeb.InviteLiveTest do
use CanneryWeb.ConnCase
import Phoenix.LiveViewTest
import CanneryWeb.Gettext
alias Cannery.Invites
alias Cannery.Accounts.Invites
@moduletag :invite_live_test
@create_attrs %{"name" => "some name"}
@ -40,13 +40,14 @@ defmodule CanneryWeb.InviteLiveTest do
# |> form("#invite-form", invite: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
{:ok, _view, html} =
{:ok, _live, 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 =~
dgettext("prompts", "%{invite_name} created successfully", invite_name: "some name")
assert html =~ "some name"
end
@ -63,14 +64,16 @@ defmodule CanneryWeb.InviteLiveTest do
# |> form("#invite-form", invite: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
{:ok, _view, html} =
{:ok, _live, 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")
dgettext("prompts", "%{invite_name} updated successfully",
invite_name: "some updated name"
)
assert html =~ "some updated name"
end

View File

@ -43,7 +43,7 @@ defmodule Cannery.DataCase do
"""
def errors_on(changeset) do
Ecto.Changeset.traverse_errors(changeset, fn {message, opts} ->
Regex.replace(~r"%{(\w+)}", message, fn _content, key ->
Regex.replace(~r"%{(\w+)}", message, fn _capture, key ->
opts |> Keyword.get(String.to_existing_atom(key), key) |> to_string()
end)
end)