Skip to content

Commit

Permalink
Add 'max_memberships', 'total_memberships' and 'can_is_private_be_upd…
Browse files Browse the repository at this point in the history
…ated' to the project serializer
  • Loading branch information
bameda committed Mar 16, 2016
1 parent 2176e9a commit f502a53
Show file tree
Hide file tree
Showing 5 changed files with 257 additions and 0 deletions.
1 change: 1 addition & 0 deletions taiga/projects/api.py
Expand Up @@ -109,6 +109,7 @@ def get_queryset(self):
# Prefetch doesn"t work correctly if then if the field is filtered later (it generates more queries)
# so we add some custom prefetching
qs = qs.prefetch_related("members")
qs = qs.prefetch_related("memberships")
qs = qs.prefetch_related(Prefetch("notify_policies",
NotifyPolicy.objects.exclude(notify_level=NotifyLevel.none), to_attr="valid_notify_policies"))

Expand Down
13 changes: 13 additions & 0 deletions taiga/projects/serializers.py
Expand Up @@ -352,11 +352,24 @@ def get_members(self, obj):


class ProjectDetailAdminSerializer(ProjectDetailSerializer):
max_memberships = serializers.SerializerMethodField(method_name="get_max_memberships")
total_memberships = serializers.SerializerMethodField(method_name="get_total_memberships")
can_is_private_be_updated = serializers.SerializerMethodField(method_name="get_can_is_private_be_updated")

class Meta:
model = models.Project
read_only_fields = ("created_date", "modified_date", "slug", "blocked_code")
exclude = ("logo", "last_us_ref", "last_task_ref", "last_issue_ref")

def get_max_memberships(self, obj):
return services.get_max_memberships_for_project(obj)

def get_total_memberships(self, obj):
return services.get_total_project_memberships(obj)

def get_can_is_private_be_updated(self, obj):
return services.check_if_project_privacity_can_be_changed(obj)


######################################################
## Liked
Expand Down
2 changes: 2 additions & 0 deletions taiga/projects/services/__init__.py
Expand Up @@ -38,6 +38,8 @@
from .members import create_members_in_bulk
from .members import get_members_from_bulk
from .members import remove_user_from_project, project_has_valid_admins, can_user_leave_project
from .members import get_max_memberships_for_project, get_total_project_memberships
from .members import check_if_project_privacity_can_be_changed

from .modules_config import get_modules_config

Expand Down
49 changes: 49 additions & 0 deletions taiga/projects/services/members.py
Expand Up @@ -60,3 +60,52 @@ def can_user_leave_project(user, project):
return False

return True


def get_max_memberships_for_project(project):
"""Return tha maximun of membersh for a concrete project.
:param project: A project object.
:return: a number or null.
"""
if project.is_private:
return project.owner.max_memberships_private_projects
return project.owner.max_memberships_public_projects


def get_total_project_memberships(project):
"""Return tha total of memberships of a project (members and unaccepted invitations).
:param project: A project object.
:return: a number.
"""
return project.memberships.count()


def check_if_project_privacity_can_be_changed(project):
"""Return if the project privacity can be changed from private to public or viceversa.
:param project: A project object.
:return: True if it can be changed or False if can't.
"""
if project.is_private:
current_projects = project.owner.owned_projects.filter(is_private=False).count()
max_projects = project.owner.max_public_projects
max_memberships = project.owner.max_memberships_public_projects
else:
current_projects = project.owner.owned_projects.filter(is_private=True).count()
max_projects = project.owner.max_private_projects
max_memberships = project.owner.max_memberships_private_projects

if max_projects is not None and current_projects >= max_projects:
return False

current_memberships = project.memberships.count()

if max_memberships is not None and current_memberships > max_memberships:
return False

return True
192 changes: 192 additions & 0 deletions tests/integration/test_projects.py
Expand Up @@ -1393,3 +1393,195 @@ def test_project_transfer_validate_token_from_admin_member_with_valid_token(clie
response = client.json.post(url, json.dumps(data))

assert response.status_code == 200


####################################################################################
# Test taiga.projects.services.members.check_if_project_privacity_can_be_changed
####################################################################################

from taiga.projects.services import check_if_project_privacity_can_be_changed

# private to public

def test_private_project_cant_be_public_because_owner_doesnt_have_enought_slot_and_too_much_members(client):
project = f.create_project(is_private=True)
f.MembershipFactory(project=project, user=project.owner)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)

project.owner.max_public_projects = 0
project.owner.max_memberships_public_projects = 3

assert check_if_project_privacity_can_be_changed(project) == False


def test_private_project_cant_be_public_because_owner_doesnt_have_enought_slot(client):
project = f.create_project(is_private=True)
f.MembershipFactory(project=project, user=project.owner)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)

project.owner.max_public_projects = 0
project.owner.max_memberships_public_projects = 6

assert check_if_project_privacity_can_be_changed(project) == False


def test_private_project_cant_be_public_because_too_much_members(client):
project = f.create_project(is_private=True)
f.MembershipFactory(project=project, user=project.owner)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)

project.owner.max_public_projects = 2
project.owner.max_memberships_public_projects = 3

assert check_if_project_privacity_can_be_changed(project) == False


def test_private_project_can_be_public_because_owner_has_enought_slot_and_project_has_enought_members(client):
project = f.create_project(is_private=True)
f.MembershipFactory(project=project, user=project.owner)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)

project.owner.max_public_projects = 2
project.owner.max_memberships_public_projects = 6

assert check_if_project_privacity_can_be_changed(project) == True


def test_private_project_can_be_public_because_owner_has_unlimited_slot_and_project_has_unlimited_members(client):
project = f.create_project(is_private=True)
f.MembershipFactory(project=project, user=project.owner)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)

project.owner.max_public_projects = None
project.owner.max_memberships_public_projects = None

assert check_if_project_privacity_can_be_changed(project) == True


def test_private_project_can_be_public_because_owner_has_unlimited_slot(client):
project = f.create_project(is_private=True)
f.MembershipFactory(project=project, user=project.owner)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)

project.owner.max_public_projects = None
project.owner.max_memberships_public_projects = 6

assert check_if_project_privacity_can_be_changed(project) == True


def test_private_project_can_be_public_because_project_has_unlimited_members(client):
project = f.create_project(is_private=True)
f.MembershipFactory(project=project, user=project.owner)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)

project.owner.max_public_projects = 2
project.owner.max_memberships_public_projects = None

assert check_if_project_privacity_can_be_changed(project) == True


# public to private

def test_public_project_cant_be_private_because_owner_doesnt_have_enought_slot_and_too_much_members(client):
project = f.create_project(is_private=False)
f.MembershipFactory(project=project, user=project.owner)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)

project.owner.max_private_projects = 0
project.owner.max_memberships_private_projects = 3

assert check_if_project_privacity_can_be_changed(project) == False


def test_public_project_cant_be_private_because_owner_doesnt_have_enought_slot(client):
project = f.create_project(is_private=False)
f.MembershipFactory(project=project, user=project.owner)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)

project.owner.max_private_projects = 0
project.owner.max_memberships_private_projects = 6

assert check_if_project_privacity_can_be_changed(project) == False


def test_public_project_cant_be_private_because_too_much_members(client):
project = f.create_project(is_private=False)
f.MembershipFactory(project=project, user=project.owner)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)

project.owner.max_private_projects = 2
project.owner.max_memberships_private_projects = 3

assert check_if_project_privacity_can_be_changed(project) == False


def test_public_project_can_be_private_because_owner_has_enought_slot_and_project_has_enought_members(client):
project = f.create_project(is_private=False)
f.MembershipFactory(project=project, user=project.owner)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)

project.owner.max_private_projects = 2
project.owner.max_memberships_private_projects = 6

assert check_if_project_privacity_can_be_changed(project) == True


def test_public_project_can_be_private_because_owner_has_unlimited_slot_and_project_has_unlimited_members(client):
project = f.create_project(is_private=False)
f.MembershipFactory(project=project, user=project.owner)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)

project.owner.max_private_projects = None
project.owner.max_memberships_private_projects = None

assert check_if_project_privacity_can_be_changed(project) == True


def test_public_project_can_be_private_because_owner_has_unlimited_slot(client):
project = f.create_project(is_private=False)
f.MembershipFactory(project=project, user=project.owner)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)

project.owner.max_private_projects = None
project.owner.max_memberships_private_projects = 6

assert check_if_project_privacity_can_be_changed(project) == True


def test_public_project_can_be_private_because_project_has_unlimited_members(client):
project = f.create_project(is_private=False)
f.MembershipFactory(project=project, user=project.owner)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)
f.MembershipFactory(project=project)

project.owner.max_private_projects = 2
project.owner.max_memberships_private_projects = None

assert check_if_project_privacity_can_be_changed(project) == True

0 comments on commit f502a53

Please sign in to comment.