analytics/test/plausible_web/controllers/invitation_controller_test.exs
Vini Brasil 303b3509f7
Feature gates (#3401)
This pull request implements limits to funnels, revenue goals and custom props based on the site owner plan. It extends the current "premium feature" notice to account for the new plans, trials and the on-going private preview. Stats API is not in the context of this pull request, but will be implemented likewise.
2023-10-11 09:40:01 -03:00

202 lines
6.0 KiB
Elixir

defmodule PlausibleWeb.Site.InvitationControllerTest do
use PlausibleWeb.ConnCase, async: true
use Plausible.Repo
use Bamboo.Test
setup [:create_user, :log_in]
describe "POST /sites/invitations/:invitation_id/accept" do
test "converts the invitation into a membership", %{conn: conn, user: user} do
site = insert(:site)
invitation =
insert(:invitation,
site_id: site.id,
inviter: build(:user),
email: user.email,
role: :admin
)
conn = post(conn, "/sites/invitations/#{invitation.invitation_id}/accept")
assert Phoenix.Flash.get(conn.assigns.flash, :success) ==
"You now have access to #{site.domain}"
assert redirected_to(conn) == "/#{site.domain}"
refute Repo.exists?(from(i in Plausible.Auth.Invitation, where: i.email == ^user.email))
membership = Repo.get_by(Plausible.Site.Membership, user_id: user.id, site_id: site.id)
assert membership.role == :admin
end
test "does not crash if clicked for the 2nd time in another tab", %{conn: conn, user: user} do
site = insert(:site)
invitation =
insert(:invitation,
site_id: site.id,
inviter: build(:user),
email: user.email,
role: :admin
)
c1 = post(conn, "/sites/invitations/#{invitation.invitation_id}/accept")
assert redirected_to(c1) == "/#{site.domain}"
assert Phoenix.Flash.get(c1.assigns.flash, :success) ==
"You now have access to #{site.domain}"
c2 = post(conn, "/sites/invitations/#{invitation.invitation_id}/accept")
assert redirected_to(c2) == "/sites"
assert Phoenix.Flash.get(c2.assigns.flash, :error) ==
"Invitation missing or already accepted"
end
end
describe "POST /sites/invitations/:invitation_id/accept - ownership transfer" do
test "downgrades previous owner to admin", %{conn: conn, user: user} do
old_owner = insert(:user)
site = insert(:site, members: [old_owner])
invitation =
insert(:invitation, site_id: site.id, inviter: old_owner, email: user.email, role: :owner)
post(conn, "/sites/invitations/#{invitation.invitation_id}/accept")
refute Repo.exists?(from(i in Plausible.Auth.Invitation, where: i.email == ^user.email))
old_owner_membership =
Repo.get_by(Plausible.Site.Membership, user_id: old_owner.id, site_id: site.id)
assert old_owner_membership.role == :admin
new_owner_membership =
Repo.get_by(Plausible.Site.Membership, user_id: user.id, site_id: site.id)
assert new_owner_membership.role == :owner
end
end
describe "POST /sites/invitations/:invitation_id/reject" do
test "rejects the invitation", %{conn: conn, user: user} do
site = insert(:site)
invitation =
insert(:invitation,
site_id: site.id,
inviter: build(:user),
email: user.email,
role: :admin
)
conn = post(conn, "/sites/invitations/#{invitation.invitation_id}/reject")
assert redirected_to(conn, 302) == "/sites"
refute Repo.reload(invitation)
end
test "renders error for non-existent invitation", %{conn: conn} do
conn = post(conn, "/sites/invitations/does-not-exist/reject")
assert redirected_to(conn, 302) == "/sites"
assert Phoenix.Flash.get(conn.assigns.flash, :error) ==
"Invitation missing or already accepted"
end
end
describe "DELETE /sites/:website/invitations/:invitation_id" do
test "removes the invitation", %{conn: conn, user: user} do
site = insert(:site, memberships: [build(:site_membership, user: user, role: :admin)])
invitation =
insert(:invitation,
site_id: site.id,
inviter: build(:user),
email: "jane@example.com",
role: :admin
)
conn =
delete(
conn,
Routes.invitation_path(conn, :remove_invitation, site.domain, invitation.invitation_id)
)
assert redirected_to(conn, 302) == "/#{site.domain}/settings/people"
refute Repo.reload(invitation)
end
test "fails to remove an invitation with insufficient permission", %{conn: conn, user: user} do
site = insert(:site, memberships: [build(:site_membership, user: user, role: :viewer)])
invitation =
insert(:invitation,
site_id: site.id,
inviter: build(:user),
email: "jane@example.com",
role: :admin
)
delete(
conn,
Routes.invitation_path(conn, :remove_invitation, site.domain, invitation.invitation_id)
)
assert Repo.reload(invitation)
end
test "fails to remove an invitation from the outside", %{conn: my_conn, user: me} do
_my_site = insert(:site, memberships: [build(:site_membership, user: me, role: "owner")])
other_user = insert(:user)
other_site =
insert(:site, memberships: [build(:site_membership, user: other_user, role: "owner")])
invitation =
insert(:invitation,
site_id: other_site.id,
inviter: other_user,
email: "jane@example.com",
role: :admin
)
remove_invitation_path =
Routes.invitation_path(
my_conn,
:remove_invitation,
other_site.domain,
invitation.invitation_id
)
delete(my_conn, remove_invitation_path)
assert Repo.reload(invitation)
end
test "renders error for non-existent invitation", %{conn: conn, user: user} do
site = insert(:site, memberships: [build(:site_membership, user: user, role: :admin)])
remove_invitation_path =
Routes.invitation_path(
conn,
:remove_invitation,
site.domain,
"does_not_exist"
)
conn = delete(conn, remove_invitation_path)
assert redirected_to(conn, 302) == "/#{site.domain}/settings/people"
assert Phoenix.Flash.get(conn.assigns.flash, :error) ==
"Invitation missing or already removed"
end
end
end