From 231f337eb52e2c083cd935e56e39f654bf64bed8 Mon Sep 17 00:00:00 2001 From: Nikola Begedin Date: Fri, 29 Dec 2017 19:12:33 +0100 Subject: [PATCH] Add tests for project user invite --- lib/code_corps/accounts/user_invites.ex | 28 ++++++ .../lib/code_corps/accounts/accounts_test.exs | 88 +++++++++++++------ 2 files changed, 87 insertions(+), 29 deletions(-) diff --git a/lib/code_corps/accounts/user_invites.ex b/lib/code_corps/accounts/user_invites.ex index 8c733e556..c40f09e15 100644 --- a/lib/code_corps/accounts/user_invites.ex +++ b/lib/code_corps/accounts/user_invites.ex @@ -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} @@ -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 @@ -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() diff --git a/test/lib/code_corps/accounts/accounts_test.exs b/test/lib/code_corps/accounts/accounts_test.exs index 7531326d6..47efe09ef 100644 --- a/test/lib/code_corps/accounts/accounts_test.exs +++ b/test/lib/code_corps/accounts/accounts_test.exs @@ -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 @@ -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 @@ -42,7 +49,7 @@ 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 @@ -50,8 +57,8 @@ defmodule CodeCorps.AccountsTest do 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 @@ -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 @@ -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] @@ -150,7 +157,7 @@ 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] @@ -158,7 +165,7 @@ defmodule CodeCorps.AccountsTest do {:error, changeset} = @base_attrs |> Map.put(:inviter_id, -1) - |> Accounts.create_invite + |> Accounts.create_invite() refute changeset.valid? refute changeset.errors[:inviter_id] @@ -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) @@ -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] @@ -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 @@ -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 @@ -279,7 +308,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_by(ProjectUser, user_id: user.id, project_id: project.id, role: "admin") end @@ -287,7 +317,7 @@ defmodule CodeCorps.AccountsTest do assert {:error, :invite_not_found} = @valid_user_params |> Map.put("invite_id", -1) - |> Accounts.claim_invite + |> Accounts.claim_invite() end end end