record invites
This commit is contained in:
		| @@ -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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user