Skip to content

Commit

Permalink
Add tests for project user invite
Browse files Browse the repository at this point in the history
  • Loading branch information
begedin committed Dec 29, 2017
1 parent 5c4909f commit 49c50ca
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 29 deletions.
28 changes: 28 additions & 0 deletions lib/code_corps/accounts/user_invites.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
defmodule CodeCorps.Accounts.UserInvites do
@moduledoc ~S"""
Subcontext for managing of `UserInvite` records
"""

alias CodeCorps.{Project, ProjectUser, Repo, User, UserInvite}
alias Ecto.{Changeset, Multi}

Expand All @@ -13,6 +17,7 @@ defmodule CodeCorps.Accounts.UserInvites do
|> Changeset.assoc_constraint(:inviter)
|> Changeset.assoc_constraint(:project)
|> ensure_email_not_owned_by_member()
|> ensure_role_and_project()
|> Repo.insert()
end

Expand Down Expand Up @@ -45,6 +50,29 @@ defmodule CodeCorps.Accounts.UserInvites do
end
end

@spec ensure_role_and_project(Changeset.t()) :: Changeset.t()
defp ensure_role_and_project(%Changeset{} = changeset) do
changes = [
changeset |> Changeset.get_field(:role),
changeset |> Changeset.get_field(:project_id)
]

case changes do
[nil, nil] ->
changeset

[nil, _project_id] ->
changeset |> Changeset.add_error(:role, "Needs to be specified for a project invite")

[_role, nil] ->
changeset
|> Changeset.add_error(:project_id, "Needs to be specified for a project invite")

[_role, _project_id] ->
changeset
end
end

@spec claim_invite(map) :: {:ok, User.t()}
def claim_invite(%{} = params) do
Multi.new()
Expand Down
88 changes: 59 additions & 29 deletions test/lib/code_corps/accounts/accounts_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,23 @@ defmodule CodeCorps.AccountsTest do
use CodeCorps.DbAccessCase

alias CodeCorps.{
Accounts, Comment, ProjectUser, Task, GitHub.TestHelpers, User, UserInvite
Accounts,
Comment,
ProjectUser,
Task,
GitHub.TestHelpers,
User,
UserInvite
}

alias Ecto.Changeset

describe "create_from_github/1" do
test "creates proper user from provided payload" do
{:ok, %User{} = user} =
"user"
|> TestHelpers.load_endpoint_fixture
|> Accounts.create_from_github
|> TestHelpers.load_endpoint_fixture()
|> Accounts.create_from_github()

assert user.id
assert user.default_color
Expand All @@ -29,7 +36,7 @@ defmodule CodeCorps.AccountsTest do

{:error, %Changeset{} = changeset} =
payload
|> Accounts.create_from_github
|> Accounts.create_from_github()

assert changeset.errors[:email] == {"has already been taken", []}
end
Expand All @@ -42,16 +49,16 @@ defmodule CodeCorps.AccountsTest do

{:error, %Changeset{} = changeset} =
payload
|> Accounts.create_from_github
|> Accounts.create_from_github()

assert changeset.errors[:github_id] == {"account is already connected to someone else", []}
end

test "uploads photo from GitHub avatar" do
{:ok, %User{} = user} =
"user"
|> TestHelpers.load_endpoint_fixture
|> Accounts.create_from_github
|> TestHelpers.load_endpoint_fixture()
|> Accounts.create_from_github()

user = Repo.get(User, user.id)
assert user.cloudinary_public_id
Expand Down Expand Up @@ -132,7 +139,7 @@ defmodule CodeCorps.AccountsTest do
{:ok, %UserInvite{} = user_invite} =
@base_attrs
|> Map.put(:inviter_id, inviter_id)
|> Accounts.create_invite
|> Accounts.create_invite()

assert Repo.one(UserInvite).id == user_invite.id
end
Expand All @@ -141,7 +148,7 @@ defmodule CodeCorps.AccountsTest do
{:error, changeset} =
@base_attrs
|> Map.delete(:email)
|> Accounts.create_invite
|> Accounts.create_invite()

refute changeset.valid?
assert changeset.errors[:email]
Expand All @@ -150,15 +157,15 @@ defmodule CodeCorps.AccountsTest do
test "requires valid inviter id" do
{:error, changeset} =
@base_attrs
|> Accounts.create_invite
|> Accounts.create_invite()

refute changeset.valid?
assert changeset.errors[:inviter_id]

{:error, changeset} =
@base_attrs
|> Map.put(:inviter_id, -1)
|> Accounts.create_invite
|> Accounts.create_invite()

refute changeset.valid?
refute changeset.errors[:inviter_id]
Expand All @@ -172,63 +179,83 @@ defmodule CodeCorps.AccountsTest do
@base_attrs
|> Map.put(:inviter_id, inviter_id)
|> Map.put(:name, "John")
|> Accounts.create_invite
|> Accounts.create_invite()

assert user_invite.name == "John"
end

test "allows specifying role" do
test "creates a user invite for a project" do
%{id: inviter_id} = insert(:user)
%{id: project_id} = insert(:project)

{:ok, %UserInvite{} = user_invite} =
@base_attrs
|> Map.put(:inviter_id, inviter_id)
|> Map.put(:role, "admin")
|> Accounts.create_invite
|> Map.put(:project_id, project_id)
|> Accounts.create_invite()

assert user_invite.role == "admin"
assert user_invite.project_id == project_id
end

test "does not allow invalid roles" do
%{id: inviter_id} = insert(:user)
%{id: project_id} = insert(:project)

{:error, changeset} =
@base_attrs
|> Map.put(:inviter_id, inviter_id)
|> Map.put(:role, "foo")
|> Accounts.create_invite
|> Map.put(:project_id, project_id)
|> Accounts.create_invite()

refute changeset.valid?
assert changeset.errors[:role]
end

test "associates with project if id provided" do
test "requires valid project id" do
%{id: inviter_id} = insert(:user)

{:error, changeset} =
@base_attrs
|> Map.put(:inviter_id, inviter_id)
|> Map.put(:project_id, -1)
|> Map.put(:role, "contributor")
|> Accounts.create_invite()

refute changeset.valid?
assert changeset.errors[:project]
end

test "requires role if project is specified" do
%{id: inviter_id} = insert(:user)
%{id: project_id} = insert(:project)

{:ok, %UserInvite{} = user_invite} =
{:error, changeset} =
@base_attrs
|> Map.put(:inviter_id, inviter_id)
|> Map.put(:project_id, project_id)
|> Accounts.create_invite
|> Accounts.create_invite()

assert user_invite.project_id == project_id
refute changeset.valid?
assert changeset.errors[:role]
end

test "requires valid project id" do
test "requires project_id if role is specified" do
%{id: inviter_id} = insert(:user)

{:error, changeset} =
@base_attrs
|> Map.put(:inviter_id, inviter_id)
|> Map.put(:project_id, -1)
|> Accounts.create_invite
|> Map.put(:role, "contributor")
|> Accounts.create_invite()

refute changeset.valid?
assert changeset.errors[:project]
assert changeset.errors[:project_id]
end

test "throws error if user is already member of project" do
test "requires user not to be member of project" do
%{id: inviter_id} = insert(:user)
%{id: project_id} = project = insert(:project)
%{email: email} = user = insert(:user)
Expand All @@ -239,7 +266,7 @@ defmodule CodeCorps.AccountsTest do
%{email: email}
|> Map.put(:inviter_id, inviter_id)
|> Map.put(:project_id, project_id)
|> Accounts.create_invite
|> Accounts.create_invite()

refute changeset.valid?
assert changeset.errors[:email]
Expand All @@ -258,7 +285,8 @@ defmodule CodeCorps.AccountsTest do
{:ok, %User{} = user} =
@valid_user_params
|> Map.put("invite_id", invite.id)
|> Accounts.claim_invite
|> Accounts.claim_invite()

assert Repo.get(User, user.id)
end

Expand All @@ -268,7 +296,8 @@ defmodule CodeCorps.AccountsTest do
{:ok, %User{} = user} =
@valid_user_params
|> Map.put("invite_id", invite.id)
|> Accounts.claim_invite
|> Accounts.claim_invite()

assert Repo.one(UserInvite).invitee_id == user.id
end

Expand All @@ -279,15 +308,16 @@ defmodule CodeCorps.AccountsTest do
{:ok, %User{} = user} =
@valid_user_params
|> Map.put("invite_id", invite.id)
|> Accounts.claim_invite
|> Accounts.claim_invite()

assert Repo.get_by(ProjectUser, user_id: user.id, project_id: project.id, role: "admin")
end

test "returns :invite_not_found if bad id provided" do
assert {:error, :invite_not_found} =
@valid_user_params
|> Map.put("invite_id", -1)
|> Accounts.claim_invite
|> Accounts.claim_invite()
end
end
end

0 comments on commit 49c50ca

Please sign in to comment.