record invites
This commit is contained in:
parent
ed8c20e967
commit
30d3f76fe1
@ -124,16 +124,15 @@ defmodule Lokal.Accounts do
|
|||||||
|> Multi.one(:users_count, from(u in User, select: count(u.id), distinct: true))
|
|> Multi.one(:users_count, from(u in User, select: count(u.id), distinct: true))
|
||||||
|> Multi.run(:use_invite, fn _changes_so_far, _repo ->
|
|> Multi.run(:use_invite, fn _changes_so_far, _repo ->
|
||||||
if allow_registration?() and invite_token |> is_nil() do
|
if allow_registration?() and invite_token |> is_nil() do
|
||||||
{:ok, :invite_not_required}
|
{:ok, nil}
|
||||||
else
|
else
|
||||||
Invites.use_invite(invite_token)
|
Invites.use_invite(invite_token)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|> Multi.insert(:add_user, fn %{users_count: count} ->
|
|> Multi.insert(:add_user, fn %{users_count: count, use_invite: invite} ->
|
||||||
# if no registered users, make first user an admin
|
# if no registered users, make first user an admin
|
||||||
role = if count == 0, do: :admin, else: :user
|
role = if count == 0, do: :admin, else: :user
|
||||||
|
User.registration_changeset(attrs, invite) |> User.role_changeset(role)
|
||||||
User.registration_changeset(attrs) |> User.role_changeset(role)
|
|
||||||
end)
|
end)
|
||||||
|> Repo.transaction()
|
|> Repo.transaction()
|
||||||
|> case do
|
|> case do
|
||||||
@ -158,7 +157,7 @@ defmodule Lokal.Accounts do
|
|||||||
@spec change_user_registration() :: User.changeset()
|
@spec change_user_registration() :: User.changeset()
|
||||||
@spec change_user_registration(attrs :: map()) :: User.changeset()
|
@spec change_user_registration(attrs :: map()) :: User.changeset()
|
||||||
def change_user_registration(attrs \\ %{}) do
|
def change_user_registration(attrs \\ %{}) do
|
||||||
User.registration_changeset(attrs, hash_password: false)
|
User.registration_changeset(attrs, nil, hash_password: false)
|
||||||
end
|
end
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
|
@ -7,7 +7,7 @@ defmodule Lokal.Accounts.Invite do
|
|||||||
|
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
alias Ecto.{Changeset, UUID}
|
alias Ecto.{Association, Changeset, UUID}
|
||||||
alias Lokal.Accounts.User
|
alias Lokal.Accounts.User
|
||||||
|
|
||||||
@primary_key {:id, :binary_id, autogenerate: true}
|
@primary_key {:id, :binary_id, autogenerate: true}
|
||||||
@ -18,7 +18,9 @@ defmodule Lokal.Accounts.Invite do
|
|||||||
field :uses_left, :integer, default: nil
|
field :uses_left, :integer, default: nil
|
||||||
field :disabled_at, :naive_datetime
|
field :disabled_at, :naive_datetime
|
||||||
|
|
||||||
belongs_to :user, User
|
belongs_to :created_by, User
|
||||||
|
|
||||||
|
has_many :users, User
|
||||||
|
|
||||||
timestamps()
|
timestamps()
|
||||||
end
|
end
|
||||||
@ -29,8 +31,9 @@ defmodule Lokal.Accounts.Invite do
|
|||||||
token: token(),
|
token: token(),
|
||||||
uses_left: integer() | nil,
|
uses_left: integer() | nil,
|
||||||
disabled_at: NaiveDateTime.t(),
|
disabled_at: NaiveDateTime.t(),
|
||||||
user: User.t(),
|
created_by: User.t() | nil | Association.NotLoaded.t(),
|
||||||
user_id: User.id(),
|
created_by_id: User.id() | nil,
|
||||||
|
users: [User.t()] | Association.NotLoaded.t(),
|
||||||
inserted_at: NaiveDateTime.t(),
|
inserted_at: NaiveDateTime.t(),
|
||||||
updated_at: NaiveDateTime.t()
|
updated_at: NaiveDateTime.t()
|
||||||
}
|
}
|
||||||
@ -43,9 +46,9 @@ defmodule Lokal.Accounts.Invite do
|
|||||||
@spec create_changeset(User.t(), token(), attrs :: map()) :: changeset()
|
@spec create_changeset(User.t(), token(), attrs :: map()) :: changeset()
|
||||||
def create_changeset(%User{id: user_id}, token, attrs) do
|
def create_changeset(%User{id: user_id}, token, attrs) do
|
||||||
%__MODULE__{}
|
%__MODULE__{}
|
||||||
|> change(token: token, user_id: user_id)
|
|> change(token: token, created_by_id: user_id)
|
||||||
|> cast(attrs, [:name, :uses_left, :disabled_at])
|
|> cast(attrs, [:name, :uses_left, :disabled_at])
|
||||||
|> validate_required([:name, :token, :user_id])
|
|> validate_required([:name, :token, :created_by_id])
|
||||||
|> validate_number(:uses_left, greater_than_or_equal_to: 0)
|
|> validate_number(:uses_left, greater_than_or_equal_to: 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -98,6 +98,15 @@ defmodule Lokal.Accounts.Invites do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec get_use_count(Invite.t(), User.t()) :: non_neg_integer()
|
||||||
|
def get_use_count(%Invite{id: invite_id}, %User{role: :admin}) do
|
||||||
|
Repo.one(
|
||||||
|
from u in User,
|
||||||
|
where: u.invite_id == ^invite_id,
|
||||||
|
select: count(u.id)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
@spec decrement_invite_changeset(Invite.t()) :: Invite.changeset()
|
@spec decrement_invite_changeset(Invite.t()) :: Invite.changeset()
|
||||||
defp decrement_invite_changeset(%Invite{uses_left: nil} = invite) do
|
defp decrement_invite_changeset(%Invite{uses_left: nil} = invite) do
|
||||||
invite |> Invite.update_changeset(%{})
|
invite |> Invite.update_changeset(%{})
|
||||||
|
@ -6,7 +6,7 @@ defmodule Lokal.Accounts.User do
|
|||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
import LokalWeb.Gettext
|
import LokalWeb.Gettext
|
||||||
alias Ecto.{Changeset, UUID}
|
alias Ecto.{Association, Changeset, UUID}
|
||||||
alias Lokal.Accounts.{Invite, User}
|
alias Lokal.Accounts.{Invite, User}
|
||||||
|
|
||||||
@derive {Jason.Encoder,
|
@derive {Jason.Encoder,
|
||||||
@ -28,7 +28,9 @@ defmodule Lokal.Accounts.User do
|
|||||||
field :role, Ecto.Enum, values: [:admin, :user], default: :user
|
field :role, Ecto.Enum, values: [:admin, :user], default: :user
|
||||||
field :locale, :string
|
field :locale, :string
|
||||||
|
|
||||||
has_many :invites, Invite, on_delete: :delete_all
|
has_many :created_invites, Invite, foreign_key: :created_by_id
|
||||||
|
|
||||||
|
belongs_to :invite, Invite
|
||||||
|
|
||||||
timestamps()
|
timestamps()
|
||||||
end
|
end
|
||||||
@ -41,7 +43,9 @@ defmodule Lokal.Accounts.User do
|
|||||||
confirmed_at: NaiveDateTime.t(),
|
confirmed_at: NaiveDateTime.t(),
|
||||||
role: role(),
|
role: role(),
|
||||||
locale: String.t() | nil,
|
locale: String.t() | nil,
|
||||||
invites: [Invite.t()],
|
created_invites: [Invite.t()] | Association.NotLoaded.t(),
|
||||||
|
invite: Invite.t() | nil | Association.NotLoaded.t(),
|
||||||
|
invite_id: Invite.id() | nil,
|
||||||
inserted_at: NaiveDateTime.t(),
|
inserted_at: NaiveDateTime.t(),
|
||||||
updated_at: NaiveDateTime.t()
|
updated_at: NaiveDateTime.t()
|
||||||
}
|
}
|
||||||
@ -67,11 +71,12 @@ defmodule Lokal.Accounts.User do
|
|||||||
validations on a LiveView form), this option can be set to `false`.
|
validations on a LiveView form), this option can be set to `false`.
|
||||||
Defaults to `true`.
|
Defaults to `true`.
|
||||||
"""
|
"""
|
||||||
@spec registration_changeset(attrs :: map()) :: changeset()
|
@spec registration_changeset(attrs :: map(), Invite.t() | nil) :: changeset()
|
||||||
@spec registration_changeset(attrs :: map(), opts :: keyword()) :: changeset()
|
@spec registration_changeset(attrs :: map(), Invite.t() | nil, opts :: keyword()) :: changeset()
|
||||||
def registration_changeset(attrs, opts \\ []) do
|
def registration_changeset(attrs, invite, opts \\ []) do
|
||||||
%User{}
|
%User{}
|
||||||
|> cast(attrs, [:email, :password, :locale])
|
|> cast(attrs, [:email, :password, :locale])
|
||||||
|
|> put_change(:invite_id, if(invite, do: invite.id))
|
||||||
|> validate_email()
|
|> validate_email()
|
||||||
|> validate_password(opts)
|
|> validate_password(opts)
|
||||||
end
|
end
|
||||||
|
@ -4,10 +4,19 @@ defmodule LokalWeb.Components.InviteCard do
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
use LokalWeb, :component
|
use LokalWeb, :component
|
||||||
|
alias Lokal.Accounts.{Invite, Invites, User}
|
||||||
alias LokalWeb.Endpoint
|
alias LokalWeb.Endpoint
|
||||||
|
|
||||||
def invite_card(assigns) do
|
attr :invite, Invite, required: true
|
||||||
assigns = assigns |> assign_new(:code_actions, fn -> [] end)
|
attr :current_user, User, required: true
|
||||||
|
slot(:inner_block)
|
||||||
|
slot(:code_actions)
|
||||||
|
|
||||||
|
def invite_card(%{invite: invite, current_user: current_user} = assigns) do
|
||||||
|
assigns =
|
||||||
|
assigns
|
||||||
|
|> assign(:use_count, Invites.get_use_count(invite, current_user))
|
||||||
|
|> assign_new(:code_actions, fn -> [] end)
|
||||||
|
|
||||||
~H"""
|
~H"""
|
||||||
<div class="mx-4 my-2 px-8 py-4 flex flex-col justify-center items-center space-y-4
|
<div class="mx-4 my-2 px-8 py-4 flex flex-col justify-center items-center space-y-4
|
||||||
@ -21,8 +30,8 @@ defmodule LokalWeb.Components.InviteCard do
|
|||||||
<h2 class="title text-md">
|
<h2 class="title text-md">
|
||||||
<%= if @invite.uses_left do %>
|
<%= if @invite.uses_left do %>
|
||||||
<%= gettext(
|
<%= gettext(
|
||||||
"Uses Left: %{uses_left}",
|
"Uses Left: %{uses_left_count}",
|
||||||
uses_left: @invite.uses_left
|
uses_left_count: @invite.uses_left
|
||||||
) %>
|
) %>
|
||||||
<% else %>
|
<% else %>
|
||||||
<%= gettext("Uses Left: Unlimited") %>
|
<%= gettext("Uses Left: Unlimited") %>
|
||||||
@ -39,6 +48,10 @@ defmodule LokalWeb.Components.InviteCard do
|
|||||||
filename={@invite.name}
|
filename={@invite.name}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<h2 :if={@use_count != 0} class="title text-md">
|
||||||
|
<%= gettext("Uses: %{uses_count}", uses_count: @use_count) %>
|
||||||
|
</h2>
|
||||||
|
|
||||||
<div class="flex flex-row flex-wrap justify-center items-center">
|
<div class="flex flex-row flex-wrap justify-center items-center">
|
||||||
<code
|
<code
|
||||||
id={"code-#{@invite.id}"}
|
id={"code-#{@invite.id}"}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<div class="w-full flex flex-row flex-wrap justify-center items-center">
|
<div class="w-full flex flex-row flex-wrap justify-center items-center">
|
||||||
<.invite_card :for={invite <- @invites} invite={invite}>
|
<.invite_card :for={invite <- @invites} invite={invite} current_user={@current_user}>
|
||||||
<:code_actions>
|
<:code_actions>
|
||||||
<form phx-submit="copy_to_clipboard">
|
<form phx-submit="copy_to_clipboard">
|
||||||
<button
|
<button
|
||||||
|
@ -31,7 +31,7 @@ msgstr ""
|
|||||||
msgid "Forgot your password?"
|
msgid "Forgot your password?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/lokal_web/components/invite_card.ex:33
|
#: lib/lokal_web/components/invite_card.ex:42
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Invite Disabled"
|
msgid "Invite Disabled"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -169,12 +169,7 @@ msgstr ""
|
|||||||
msgid "User was confirmed at%{confirmed_datetime}"
|
msgid "User was confirmed at%{confirmed_datetime}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/lokal_web/components/invite_card.ex:23
|
#: lib/lokal_web/components/invite_card.ex:37
|
||||||
#, elixir-autogen, elixir-format
|
|
||||||
msgid "Uses Left: %{uses_left}"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/lokal_web/components/invite_card.ex:28
|
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Uses Left: Unlimited"
|
msgid "Uses Left: Unlimited"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -278,3 +273,13 @@ msgstr ""
|
|||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Lokal | %{title}"
|
msgid "Lokal | %{title}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/lokal_web/components/invite_card.ex:32
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Uses Left: %{uses_left_count}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/lokal_web/components/invite_card.ex:52
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Uses: %{uses_count}"
|
||||||
|
msgstr ""
|
||||||
|
@ -31,7 +31,7 @@ msgstr ""
|
|||||||
msgid "Forgot your password?"
|
msgid "Forgot your password?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/lokal_web/components/invite_card.ex:33
|
#: lib/lokal_web/components/invite_card.ex:42
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Invite Disabled"
|
msgid "Invite Disabled"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -169,12 +169,7 @@ msgstr ""
|
|||||||
msgid "User was confirmed at%{confirmed_datetime}"
|
msgid "User was confirmed at%{confirmed_datetime}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/lokal_web/components/invite_card.ex:23
|
#: lib/lokal_web/components/invite_card.ex:37
|
||||||
#, elixir-autogen, elixir-format, fuzzy
|
|
||||||
msgid "Uses Left: %{uses_left}"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/lokal_web/components/invite_card.ex:28
|
|
||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "Uses Left: Unlimited"
|
msgid "Uses Left: Unlimited"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -278,3 +273,13 @@ msgstr ""
|
|||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Lokal | %{title}"
|
msgid "Lokal | %{title}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/lokal_web/components/invite_card.ex:32
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "Uses Left: %{uses_left_count}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/lokal_web/components/invite_card.ex:52
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Uses: %{uses_count}"
|
||||||
|
msgstr ""
|
||||||
|
@ -179,22 +179,22 @@ msgstr ""
|
|||||||
msgid "You must confirm your account and log in to access this page."
|
msgid "You must confirm your account and log in to access this page."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/lokal/accounts/user.ex:137
|
#: lib/lokal/accounts/user.ex:142
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "did not change"
|
msgid "did not change"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/lokal/accounts/user.ex:158
|
#: lib/lokal/accounts/user.ex:163
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "does not match password"
|
msgid "does not match password"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/lokal/accounts/user.ex:195
|
#: lib/lokal/accounts/user.ex:200
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "is not valid"
|
msgid "is not valid"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/lokal/accounts/user.ex:92
|
#: lib/lokal/accounts/user.ex:97
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "must have the @ sign and no spaces"
|
msgid "must have the @ sign and no spaces"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -176,22 +176,22 @@ msgstr ""
|
|||||||
msgid "You must confirm your account and log in to access this page."
|
msgid "You must confirm your account and log in to access this page."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/lokal/accounts/user.ex:137
|
#: lib/lokal/accounts/user.ex:142
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "did not change"
|
msgid "did not change"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/lokal/accounts/user.ex:158
|
#: lib/lokal/accounts/user.ex:163
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "does not match password"
|
msgid "does not match password"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/lokal/accounts/user.ex:195
|
#: lib/lokal/accounts/user.ex:200
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "is not valid"
|
msgid "is not valid"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/lokal/accounts/user.ex:92
|
#: lib/lokal/accounts/user.ex:97
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "must have the @ sign and no spaces"
|
msgid "must have the @ sign and no spaces"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
11
priv/repo/migrations/20230204191547_record_invites.exs
Normal file
11
priv/repo/migrations/20230204191547_record_invites.exs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
defmodule Lokal.Repo.Migrations.RecordInvites do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def change do
|
||||||
|
alter table(:users) do
|
||||||
|
add :invite_id, references(:invites, type: :binary_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
rename table(:invites), :user_id, to: :created_by_id
|
||||||
|
end
|
||||||
|
end
|
@ -5,17 +5,13 @@ defmodule Lokal.InvitesTest do
|
|||||||
|
|
||||||
use Lokal.DataCase
|
use Lokal.DataCase
|
||||||
alias Ecto.Changeset
|
alias Ecto.Changeset
|
||||||
|
alias Lokal.Accounts
|
||||||
alias Lokal.Accounts.{Invite, Invites}
|
alias Lokal.Accounts.{Invite, Invites}
|
||||||
|
|
||||||
@moduletag :invites_test
|
@moduletag :invites_test
|
||||||
|
|
||||||
@valid_attrs %{
|
@valid_attrs %{
|
||||||
"name" => "some name",
|
"name" => "some name"
|
||||||
"uses_left" => 10
|
|
||||||
}
|
|
||||||
@update_attrs %{
|
|
||||||
"name" => "some updated name",
|
|
||||||
"uses_left" => 5
|
|
||||||
}
|
}
|
||||||
@invalid_attrs %{
|
@invalid_attrs %{
|
||||||
"name" => nil,
|
"name" => nil,
|
||||||
@ -55,6 +51,27 @@ defmodule Lokal.InvitesTest do
|
|||||||
refute Invites.valid_invite_token?(token)
|
refute Invites.valid_invite_token?(token)
|
||||||
end
|
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",
|
test "use_invite/1 successfully uses an unlimited invite",
|
||||||
%{invite: %{token: token} = invite, current_user: current_user} do
|
%{invite: %{token: token} = invite, current_user: current_user} do
|
||||||
{:ok, invite} = Invites.update_invite(invite, %{uses_left: nil}, current_user)
|
{:ok, invite} = Invites.update_invite(invite, %{uses_left: nil}, current_user)
|
||||||
@ -63,7 +80,9 @@ defmodule Lokal.InvitesTest do
|
|||||||
assert {:ok, ^invite} = Invites.use_invite(token)
|
assert {:ok, ^invite} = Invites.use_invite(token)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "use_invite/1 successfully decrements an invite", %{invite: %{token: token}} do
|
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: 9}} = Invites.use_invite(token)
|
||||||
assert {:ok, %{uses_left: 8}} = Invites.use_invite(token)
|
assert {:ok, %{uses_left: 8}} = Invites.use_invite(token)
|
||||||
assert {:ok, %{uses_left: 7}} = Invites.use_invite(token)
|
assert {:ok, %{uses_left: 7}} = Invites.use_invite(token)
|
||||||
@ -83,26 +102,61 @@ defmodule Lokal.InvitesTest do
|
|||||||
assert {:error, :invalid_token} = Invites.use_invite(token)
|
assert {:error, :invalid_token} = Invites.use_invite(token)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "create_invite/1 with valid data creates a invite",
|
test "create_invite/1 with valid data creates an unlimited invite",
|
||||||
%{current_user: current_user} do
|
%{current_user: current_user} do
|
||||||
assert {:ok, %Invite{} = invite} = Invites.create_invite(current_user, @valid_attrs)
|
assert {:ok, %Invite{} = invite} =
|
||||||
|
Invites.create_invite(current_user, %{
|
||||||
|
"name" => "some name"
|
||||||
|
})
|
||||||
|
|
||||||
assert invite.name == "some name"
|
assert invite.name == "some name"
|
||||||
end
|
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",
|
test "create_invite/1 with invalid data returns error changeset",
|
||||||
%{current_user: current_user} do
|
%{current_user: current_user} do
|
||||||
assert {:error, %Changeset{}} = Invites.create_invite(current_user, @invalid_attrs)
|
assert {:error, %Changeset{}} = Invites.create_invite(current_user, @invalid_attrs)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "update_invite/2 with valid data updates the invite",
|
test "update_invite/2 can set an invite to be limited",
|
||||||
%{invite: invite, current_user: current_user} do
|
%{invite: invite, current_user: current_user} do
|
||||||
assert {:ok, %Invite{} = new_invite} =
|
assert {:ok, %Invite{} = new_invite} =
|
||||||
Invites.update_invite(invite, @update_attrs, current_user)
|
Invites.update_invite(
|
||||||
|
invite,
|
||||||
|
%{"name" => "some updated name", "uses_left" => 5},
|
||||||
|
current_user
|
||||||
|
)
|
||||||
|
|
||||||
assert new_invite.name == "some updated name"
|
assert new_invite.name == "some updated name"
|
||||||
assert new_invite.uses_left == 5
|
assert new_invite.uses_left == 5
|
||||||
end
|
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",
|
test "update_invite/2 with invalid data returns error changeset",
|
||||||
%{invite: invite, current_user: current_user} do
|
%{invite: invite, current_user: current_user} do
|
||||||
assert {:error, %Changeset{}} = Invites.update_invite(invite, @invalid_attrs, current_user)
|
assert {:error, %Changeset{}} = Invites.update_invite(invite, @invalid_attrs, current_user)
|
||||||
|
@ -6,7 +6,7 @@ defmodule Lokal.AccountsTest do
|
|||||||
use Lokal.DataCase
|
use Lokal.DataCase
|
||||||
alias Ecto.Changeset
|
alias Ecto.Changeset
|
||||||
alias Lokal.Accounts
|
alias Lokal.Accounts
|
||||||
alias Lokal.Accounts.{User, UserToken}
|
alias Lokal.Accounts.{Invites, User, UserToken}
|
||||||
|
|
||||||
@moduletag :accounts_test
|
@moduletag :accounts_test
|
||||||
|
|
||||||
@ -102,6 +102,17 @@ defmodule Lokal.AccountsTest do
|
|||||||
assert is_nil(user.confirmed_at)
|
assert is_nil(user.confirmed_at)
|
||||||
assert is_nil(user.password)
|
assert is_nil(user.password)
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
describe "change_user_registration/2" do
|
describe "change_user_registration/2" do
|
||||||
|
Loading…
Reference in New Issue
Block a user