Refactoring notify policies
parent
e4369fa09e
commit
a9710fee7c
|
@ -32,6 +32,7 @@ from taiga.base.utils.slug import slugify_uniquely
|
||||||
|
|
||||||
from taiga.projects.history.mixins import HistoryResourceMixin
|
from taiga.projects.history.mixins import HistoryResourceMixin
|
||||||
from taiga.projects.notifications.mixins import WatchedResourceMixin, WatchersViewSetMixin
|
from taiga.projects.notifications.mixins import WatchedResourceMixin, WatchersViewSetMixin
|
||||||
|
from taiga.projects.notifications.services import set_notify_policy
|
||||||
from taiga.projects.mixins.ordering import BulkUpdateOrderMixin
|
from taiga.projects.mixins.ordering import BulkUpdateOrderMixin
|
||||||
from taiga.projects.mixins.on_destroy import MoveOnDestroyMixin
|
from taiga.projects.mixins.on_destroy import MoveOnDestroyMixin
|
||||||
|
|
||||||
|
@ -66,6 +67,16 @@ class ProjectViewSet(LikedResourceMixin, HistoryResourceMixin, WatchedResourceMi
|
||||||
qs = self.attach_votes_attrs_to_queryset(qs)
|
qs = self.attach_votes_attrs_to_queryset(qs)
|
||||||
return self.attach_watchers_attrs_to_queryset(qs)
|
return self.attach_watchers_attrs_to_queryset(qs)
|
||||||
|
|
||||||
|
@detail_route(methods=["POST"])
|
||||||
|
def watch(self, request, pk=None):
|
||||||
|
response = super(ProjectViewSet, self).watch(request, pk)
|
||||||
|
notify_policy = self.get_object().notify_policies.get(user=request.user)
|
||||||
|
level = request.DATA.get("notify_level", None)
|
||||||
|
if level is not None:
|
||||||
|
set_notify_policy(notify_policy, level)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
@list_route(methods=["POST"])
|
@list_route(methods=["POST"])
|
||||||
def bulk_update_order(self, request, **kwargs):
|
def bulk_update_order(self, request, **kwargs):
|
||||||
if self.request.user.is_anonymous():
|
if self.request.user.is_anonymous():
|
||||||
|
|
|
@ -33,13 +33,12 @@ class NotifyPolicyViewSet(ModelCrudViewSet):
|
||||||
permission_classes = (permissions.NotifyPolicyPermission,)
|
permission_classes = (permissions.NotifyPolicyPermission,)
|
||||||
|
|
||||||
def _build_needed_notify_policies(self):
|
def _build_needed_notify_policies(self):
|
||||||
watched_content = user_services.get_watched_content_for_user(self.request.user)
|
watched_project_ids = user_services.get_watched_content_for_user(self.request.user).get("project", [])
|
||||||
watched_content_project_ids = watched_content.values_list("project__id", flat=True).distinct()
|
|
||||||
|
|
||||||
projects = Project.objects.filter(
|
projects = Project.objects.filter(
|
||||||
Q(owner=self.request.user) |
|
Q(owner=self.request.user) |
|
||||||
Q(memberships__user=self.request.user) |
|
Q(memberships__user=self.request.user) |
|
||||||
Q(id__in=watched_content_project_ids)
|
Q(id__in=watched_project_ids)
|
||||||
).distinct()
|
).distinct()
|
||||||
|
|
||||||
for project in projects:
|
for project in projects:
|
||||||
|
@ -54,10 +53,10 @@ class NotifyPolicyViewSet(ModelCrudViewSet):
|
||||||
# With really want to include the policies related to any content:
|
# With really want to include the policies related to any content:
|
||||||
# - The user is the owner of the project
|
# - The user is the owner of the project
|
||||||
# - The user is member of the project
|
# - The user is member of the project
|
||||||
# - The user is watching any object from the project
|
# - The user is watching the project
|
||||||
watched_content = user_services.get_watched_content_for_user(self.request.user)
|
watched_project_ids = user_services.get_watched_content_for_user(self.request.user).get("project", [])
|
||||||
watched_content_project_ids = watched_content.values_list("project__id", flat=True).distinct()
|
|
||||||
return models.NotifyPolicy.objects.filter(Q(project__owner=self.request.user) |
|
return models.NotifyPolicy.objects.filter(user=self.request.user).filter(Q(project__owner=self.request.user) |
|
||||||
Q(project__memberships__user=self.request.user) |
|
Q(project__memberships__user=self.request.user) |
|
||||||
Q(project__id__in=watched_content_project_ids)
|
Q(project__id__in=watched_project_ids)
|
||||||
).distinct()
|
).distinct()
|
||||||
|
|
|
@ -356,3 +356,14 @@ def remove_watcher(obj, user):
|
||||||
return
|
return
|
||||||
|
|
||||||
qs.delete()
|
qs.delete()
|
||||||
|
|
||||||
|
|
||||||
|
def set_notify_policy(notify_policy, notify_level):
|
||||||
|
"""
|
||||||
|
Set notification level for specified policy.
|
||||||
|
"""
|
||||||
|
if not notify_level in [e.value for e in NotifyLevel]:
|
||||||
|
raise exc.IntegrityError(_("Invalid value for notify level"))
|
||||||
|
|
||||||
|
notify_policy.notify_level = notify_level
|
||||||
|
notify_policy.save()
|
||||||
|
|
|
@ -36,6 +36,9 @@ from taiga.users.validators import RoleExistsValidator
|
||||||
from taiga.permissions.service import get_user_project_permissions
|
from taiga.permissions.service import get_user_project_permissions
|
||||||
from taiga.permissions.service import is_project_owner
|
from taiga.permissions.service import is_project_owner
|
||||||
|
|
||||||
|
from taiga.projects.notifications import models as notify_models
|
||||||
|
from taiga.projects.notifications import serializers as notify_serializers
|
||||||
|
|
||||||
from . import models
|
from . import models
|
||||||
from . import services
|
from . import services
|
||||||
from .validators import ProjectExistsValidator
|
from .validators import ProjectExistsValidator
|
||||||
|
@ -367,6 +370,7 @@ class ProjectDetailSerializer(ProjectSerializer):
|
||||||
|
|
||||||
roles = ProjectRoleSerializer(source="roles", many=True, read_only=True)
|
roles = ProjectRoleSerializer(source="roles", many=True, read_only=True)
|
||||||
members = serializers.SerializerMethodField(method_name="get_members")
|
members = serializers.SerializerMethodField(method_name="get_members")
|
||||||
|
notify_policy = serializers.SerializerMethodField(method_name="get_notify_policy")
|
||||||
|
|
||||||
def get_members(self, obj):
|
def get_members(self, obj):
|
||||||
qs = obj.memberships.filter(user__isnull=False)
|
qs = obj.memberships.filter(user__isnull=False)
|
||||||
|
@ -376,6 +380,22 @@ class ProjectDetailSerializer(ProjectSerializer):
|
||||||
serializer = ProjectMemberSerializer(qs, many=True)
|
serializer = ProjectMemberSerializer(qs, many=True)
|
||||||
return serializer.data
|
return serializer.data
|
||||||
|
|
||||||
|
def get_notify_policy(self, obj):
|
||||||
|
request= self.context.get("request", None)
|
||||||
|
if request is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
user = request.user
|
||||||
|
if not user.is_authenticated():
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
notify_policy = obj.notify_policies.get(user=user, project=obj)
|
||||||
|
return notify_serializers.NotifyPolicySerializer(notify_policy).data
|
||||||
|
|
||||||
|
except notify_models.NotifyPolicy.DoesNotExist:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class ProjectDetailAdminSerializer(ProjectDetailSerializer):
|
class ProjectDetailAdminSerializer(ProjectDetailSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
@ -36,6 +36,37 @@ def test_watch_project(client):
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
def test_watch_project_with_valid_notify_level(client):
|
||||||
|
user = f.UserFactory.create()
|
||||||
|
project = f.create_project(owner=user)
|
||||||
|
f.MembershipFactory.create(project=project, user=user, is_owner=True)
|
||||||
|
url = reverse("projects-watch", args=(project.id,))
|
||||||
|
|
||||||
|
client.login(user)
|
||||||
|
data = {
|
||||||
|
"notify_level": 1
|
||||||
|
}
|
||||||
|
response = client.json.post(url, json.dumps(data))
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
def test_watch_project_with_invalid_notify_level(client):
|
||||||
|
user = f.UserFactory.create()
|
||||||
|
project = f.create_project(owner=user)
|
||||||
|
f.MembershipFactory.create(project=project, user=user, is_owner=True)
|
||||||
|
url = reverse("projects-watch", args=(project.id,))
|
||||||
|
|
||||||
|
client.login(user)
|
||||||
|
data = {
|
||||||
|
"notify_level": 333
|
||||||
|
}
|
||||||
|
response = client.json.post(url, json.dumps(data))
|
||||||
|
|
||||||
|
assert response.status_code == 400
|
||||||
|
assert response.data["_error_message"] == "Invalid value for notify level"
|
||||||
|
|
||||||
|
|
||||||
def test_unwacth_project(client):
|
def test_unwacth_project(client):
|
||||||
user = f.UserFactory.create()
|
user = f.UserFactory.create()
|
||||||
project = f.create_project(owner=user)
|
project = f.create_project(owner=user)
|
||||||
|
|
Loading…
Reference in New Issue