From a9710fee7ca65ef85da4709fdfe99cecb8be58dd Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Wed, 2 Sep 2015 11:20:07 +0200 Subject: [PATCH] Refactoring notify policies --- taiga/projects/api.py | 11 +++++++++ taiga/projects/notifications/api.py | 15 ++++++------ taiga/projects/notifications/services.py | 11 +++++++++ taiga/projects/serializers.py | 20 +++++++++++++++ tests/integration/test_watch_projects.py | 31 ++++++++++++++++++++++++ 5 files changed, 80 insertions(+), 8 deletions(-) diff --git a/taiga/projects/api.py b/taiga/projects/api.py index baaa0eb0..93b08a87 100644 --- a/taiga/projects/api.py +++ b/taiga/projects/api.py @@ -32,6 +32,7 @@ from taiga.base.utils.slug import slugify_uniquely from taiga.projects.history.mixins import HistoryResourceMixin 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.on_destroy import MoveOnDestroyMixin @@ -66,6 +67,16 @@ class ProjectViewSet(LikedResourceMixin, HistoryResourceMixin, WatchedResourceMi qs = self.attach_votes_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"]) def bulk_update_order(self, request, **kwargs): if self.request.user.is_anonymous(): diff --git a/taiga/projects/notifications/api.py b/taiga/projects/notifications/api.py index b2f2d260..453df821 100644 --- a/taiga/projects/notifications/api.py +++ b/taiga/projects/notifications/api.py @@ -33,13 +33,12 @@ class NotifyPolicyViewSet(ModelCrudViewSet): permission_classes = (permissions.NotifyPolicyPermission,) def _build_needed_notify_policies(self): - watched_content = user_services.get_watched_content_for_user(self.request.user) - watched_content_project_ids = watched_content.values_list("project__id", flat=True).distinct() + watched_project_ids = user_services.get_watched_content_for_user(self.request.user).get("project", []) projects = Project.objects.filter( Q(owner=self.request.user) | Q(memberships__user=self.request.user) | - Q(id__in=watched_content_project_ids) + Q(id__in=watched_project_ids) ).distinct() for project in projects: @@ -54,10 +53,10 @@ class NotifyPolicyViewSet(ModelCrudViewSet): # With really want to include the policies related to any content: # - The user is the owner of the project # - The user is member of the project - # - The user is watching any object from the project - watched_content = user_services.get_watched_content_for_user(self.request.user) - watched_content_project_ids = watched_content.values_list("project__id", flat=True).distinct() - return models.NotifyPolicy.objects.filter(Q(project__owner=self.request.user) | + # - The user is watching the project + watched_project_ids = user_services.get_watched_content_for_user(self.request.user).get("project", []) + + 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__id__in=watched_content_project_ids) + Q(project__id__in=watched_project_ids) ).distinct() diff --git a/taiga/projects/notifications/services.py b/taiga/projects/notifications/services.py index adc94a69..778e2770 100644 --- a/taiga/projects/notifications/services.py +++ b/taiga/projects/notifications/services.py @@ -356,3 +356,14 @@ def remove_watcher(obj, user): return 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() diff --git a/taiga/projects/serializers.py b/taiga/projects/serializers.py index c4f5f506..44812e51 100644 --- a/taiga/projects/serializers.py +++ b/taiga/projects/serializers.py @@ -36,6 +36,9 @@ from taiga.users.validators import RoleExistsValidator from taiga.permissions.service import get_user_project_permissions 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 services from .validators import ProjectExistsValidator @@ -367,6 +370,7 @@ class ProjectDetailSerializer(ProjectSerializer): roles = ProjectRoleSerializer(source="roles", many=True, read_only=True) members = serializers.SerializerMethodField(method_name="get_members") + notify_policy = serializers.SerializerMethodField(method_name="get_notify_policy") def get_members(self, obj): qs = obj.memberships.filter(user__isnull=False) @@ -376,6 +380,22 @@ class ProjectDetailSerializer(ProjectSerializer): serializer = ProjectMemberSerializer(qs, many=True) 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 Meta: diff --git a/tests/integration/test_watch_projects.py b/tests/integration/test_watch_projects.py index 358c15f2..5d643eb4 100644 --- a/tests/integration/test_watch_projects.py +++ b/tests/integration/test_watch_projects.py @@ -36,6 +36,37 @@ def test_watch_project(client): 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): user = f.UserFactory.create() project = f.create_project(owner=user)