intent/tests/test_org_services.py

100 lines
3.7 KiB
Python
Raw Permalink Normal View History

from datetime import timedelta
import pytest
from django.core.exceptions import PermissionDenied, ValidationError
from django.utils import timezone
from intent.orgs import services
from intent.orgs.models import InviteStatus, OrgMembership, Role, validate_org_slug
def test_create_org_makes_creator_owner(owner, org):
assert org.memberships.get(user=owner).role == Role.OWNER
def test_staff_cannot_own_org(make_user):
with pytest.raises(ValidationError):
services.create_org(slug="x", name="X", owner=make_user(is_staff=True))
def test_reserved_slug_rejected():
with pytest.raises(ValidationError):
validate_org_slug("Admin")
def test_invite_requires_owner(collaborator, make_user, org):
with pytest.raises(PermissionDenied):
services.invite(org, collaborator, user=make_user())
def test_reinvite_replaces_pending_invite(owner, make_user, org):
invitee = make_user()
first, _ = services.invite(org, owner, user=invitee)
second, _ = services.invite(org, owner, user=invitee, role=Role.OWNER)
first.refresh_from_db()
assert first.status == InviteStatus.REVOKED
assert second.status == InviteStatus.PENDING
def test_cannot_invite_existing_member_or_staff(owner, collaborator, make_user, org):
with pytest.raises(ValidationError):
services.invite(org, owner, user=collaborator)
with pytest.raises(ValidationError):
services.invite(org, owner, email="COLE@example.com")
with pytest.raises(ValidationError):
services.invite(org, owner, user=make_user(is_staff=True))
def test_accept_creates_membership_with_invited_role(owner, make_user, org):
invitee = make_user()
invite, _ = services.invite(org, owner, user=invitee, role=Role.OWNER)
services.accept_invite(invite, invitee)
assert org.memberships.get(user=invitee).role == Role.OWNER
invite.refresh_from_db()
assert invite.status == InviteStatus.ACCEPTED
assert invite.accepted_by == invitee
def test_expired_invite_cannot_be_accepted(owner, make_user, org):
invitee = make_user()
invite, _ = services.invite(org, owner, user=invitee)
invite.expires_at = timezone.now() - timedelta(seconds=1)
invite.save()
with pytest.raises(ValidationError):
services.accept_invite(invite, invitee)
def test_email_invite_is_found_by_verified_email(owner, make_user, org):
invitee = make_user("ivy")
invite, _ = services.invite(org, owner, email="Ivy@Example.com")
assert list(services.open_invites_for(invitee)) == [invite]
assert services.is_addressed_to(invite, invitee)
assert not services.is_addressed_to(invite, make_user())
def test_last_owner_cannot_leave_or_be_demoted(owner, org):
membership = org.memberships.get(user=owner)
with pytest.raises(ValidationError):
services.remove_member(membership, owner)
with pytest.raises(ValidationError):
services.update_membership(
membership, owner, role=Role.COLLABORATOR, can_create_projects=False
)
def test_owner_can_step_down_once_another_owner_exists(owner, collaborator, org):
services.update_membership(
org.memberships.get(user=collaborator), owner, role=Role.OWNER, can_create_projects=False
)
services.remove_member(org.memberships.get(user=owner), owner)
assert not org.memberships.filter(user=owner).exists()
def test_member_can_leave_but_not_remove_others(owner, collaborator, make_user, org):
other = make_user()
OrgMembership.objects.create(org=org, user=other)
with pytest.raises(PermissionDenied):
services.remove_member(org.memberships.get(user=other), collaborator)
services.remove_member(org.memberships.get(user=collaborator), collaborator)
assert not org.memberships.filter(user=collaborator).exists()