Add 'max_memberships', 'total_memberships' and 'can_is_private_be_updated' to the project serializer
parent
2176e9a0af
commit
f502a538c2
|
@ -109,6 +109,7 @@ class ProjectViewSet(LikedResourceMixin, HistoryResourceMixin,
|
|||
# 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"))
|
||||
|
||||
|
|
|
@ -352,11 +352,24 @@ class ProjectDetailSerializer(ProjectSerializer):
|
|||
|
||||
|
||||
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
|
||||
|
|
|
@ -38,6 +38,8 @@ from .logo import get_logo_big_thumbnail_url
|
|||
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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue