diff --git a/taiga/locale/en/LC_MESSAGES/django.po b/taiga/locale/en/LC_MESSAGES/django.po index 38e42ee3..13f273ce 100644 --- a/taiga/locale/en/LC_MESSAGES/django.po +++ b/taiga/locale/en/LC_MESSAGES/django.po @@ -1673,15 +1673,15 @@ msgid "roles" msgstr "" #: taiga/projects/notifications/choices.py:28 -msgid "Not watching" +msgid "Involved" msgstr "" #: taiga/projects/notifications/choices.py:29 -msgid "Watching" +msgid "All" msgstr "" #: taiga/projects/notifications/choices.py:30 -msgid "Ignoring" +msgid "None" msgstr "" #: taiga/projects/notifications/models.py:61 diff --git a/taiga/projects/api.py b/taiga/projects/api.py index 4b3c47aa..ceebb2f7 100644 --- a/taiga/projects/api.py +++ b/taiga/projects/api.py @@ -80,7 +80,7 @@ class ProjectViewSet(LikedResourceMixin, HistoryResourceMixin, ModelCrudViewSet) def watch(self, request, pk=None): project = self.get_object() self.check_permissions(request, "watch", project) - notify_level = request.DATA.get("notify_level", NotifyLevel.watch) + notify_level = request.DATA.get("notify_level", NotifyLevel.all) project.add_watcher(self.request.user, notify_level=notify_level) return response.Ok() diff --git a/taiga/projects/management/commands/sample_data.py b/taiga/projects/management/commands/sample_data.py index f25ba274..8cc587a0 100644 --- a/taiga/projects/management/commands/sample_data.py +++ b/taiga/projects/management/commands/sample_data.py @@ -29,6 +29,8 @@ from taiga.users.models import * from taiga.permissions.permissions import ANON_PERMISSIONS from taiga.projects.models import * from taiga.projects.milestones.models import * +from taiga.projects.notifications.choices import NotifyLevel + from taiga.projects.userstories.models import * from taiga.projects.tasks.models import * from taiga.projects.issues.models import * @@ -459,7 +461,7 @@ class Command(BaseCommand): take_snapshot(project, user=project.owner) self.create_likes(project) - self.create_watchers(project) + self.create_watchers(project, NotifyLevel.involved) return project @@ -490,7 +492,11 @@ class Command(BaseCommand): user=self.sd.db_object_from_queryset(User.objects.all()) add_like(obj, user) - def create_watchers(self, obj): + def create_watchers(self, obj, notify_level=None): for i in range(self.sd.int(*NUM_WATCHERS)): user = self.sd.db_object_from_queryset(User.objects.all()) - obj.add_watcher(user) + if not notify_level: + obj.add_watcher(user) + else: + obj.add_watcher(user, notify_level) + diff --git a/taiga/projects/models.py b/taiga/projects/models.py index c0455e4b..1bc8ab4d 100644 --- a/taiga/projects/models.py +++ b/taiga/projects/models.py @@ -344,7 +344,7 @@ class Project(ProjectDefaults, TaggedMixin, models.Model): } def _get_q_watchers(self): - return Q(notify_policies__project_id=self.id) & ~Q(notify_policies__notify_level=NotifyLevel.ignore) + return Q(notify_policies__project_id=self.id) & ~Q(notify_policies__notify_level=NotifyLevel.none) def get_watchers(self): return get_user_model().objects.filter(self._get_q_watchers()) @@ -368,7 +368,7 @@ class Project(ProjectDefaults, TaggedMixin, models.Model): related_people = related_people.distinct() return related_people - def add_watcher(self, user, notify_level=NotifyLevel.watch): + def add_watcher(self, user, notify_level=NotifyLevel.all): notify_policy = create_notify_policy_if_not_exists(self, user) set_notify_policy_level(notify_policy, notify_level) diff --git a/taiga/projects/notifications/api.py b/taiga/projects/notifications/api.py index 0d497be4..26b8440f 100644 --- a/taiga/projects/notifications/api.py +++ b/taiga/projects/notifications/api.py @@ -39,7 +39,7 @@ class NotifyPolicyViewSet(ModelCrudViewSet): ).distinct() for project in projects: - services.create_notify_policy_if_not_exists(project, self.request.user, NotifyLevel.watch) + services.create_notify_policy_if_not_exists(project, self.request.user, NotifyLevel.all) def get_queryset(self): if self.request.user.is_anonymous(): diff --git a/taiga/projects/notifications/choices.py b/taiga/projects/notifications/choices.py index 651d5909..e42d9c91 100644 --- a/taiga/projects/notifications/choices.py +++ b/taiga/projects/notifications/choices.py @@ -19,13 +19,13 @@ from django.utils.translation import ugettext_lazy as _ class NotifyLevel(enum.IntEnum): - notwatch = 1 - watch = 2 - ignore = 3 + involved = 1 + all = 2 + none = 3 NOTIFY_LEVEL_CHOICES = ( - (NotifyLevel.notwatch, _("Not watching")), - (NotifyLevel.watch, _("Watching")), - (NotifyLevel.ignore, _("Ignoring")), + (NotifyLevel.involved, _("Involved")), + (NotifyLevel.all, _("All")), + (NotifyLevel.none, _("None")), ) diff --git a/taiga/projects/notifications/services.py b/taiga/projects/notifications/services.py index be6dc949..2be1c8fc 100644 --- a/taiga/projects/notifications/services.py +++ b/taiga/projects/notifications/services.py @@ -52,7 +52,7 @@ def notify_policy_exists(project, user) -> bool: return qs.exists() -def create_notify_policy(project, user, level=NotifyLevel.notwatch): +def create_notify_policy(project, user, level=NotifyLevel.involved): """ Given a project and user, create notification policy for it. """ @@ -65,7 +65,7 @@ def create_notify_policy(project, user, level=NotifyLevel.notwatch): raise exc.IntegrityError(_("Notify exists for specified user and project")) from e -def create_notify_policy_if_not_exists(project, user, level=NotifyLevel.notwatch): +def create_notify_policy_if_not_exists(project, user, level=NotifyLevel.involved): """ Given a project and user, create notification policy for it. """ @@ -85,7 +85,7 @@ def get_notify_policy(project, user): """ model_cls = apps.get_model("notifications", "NotifyPolicy") instance, _ = model_cls.objects.get_or_create(project=project, user=user, - defaults={"notify_level": NotifyLevel.notwatch}) + defaults={"notify_level": NotifyLevel.involved}) return instance @@ -154,9 +154,9 @@ def get_users_to_notify(obj, *, discard_users=None) -> list: return policy.notify_level in [int(x) for x in levels] _can_notify_hard = partial(_check_level, project, - levels=[NotifyLevel.watch]) + levels=[NotifyLevel.all]) _can_notify_light = partial(_check_level, project, - levels=[NotifyLevel.watch, NotifyLevel.notwatch]) + levels=[NotifyLevel.all, NotifyLevel.involved]) candidates = set() candidates.update(filter(_can_notify_hard, project.members.all())) @@ -381,7 +381,7 @@ def get_projects_watched(user_or_id): user_id = user_or_id project_class = apps.get_model("projects", "Project") - return project_class.objects.filter(notify_policies__user__id=user_id).exclude(notify_policies__notify_level=NotifyLevel.ignore) + return project_class.objects.filter(notify_policies__user__id=user_id).exclude(notify_policies__notify_level=NotifyLevel.none) def add_watcher(obj, user): """Add a watcher to an object. @@ -397,7 +397,7 @@ def add_watcher(obj, user): object_id=obj.id, user=user, project=obj.project) notify_policy, _ = apps.get_model("notifications", "NotifyPolicy").objects.get_or_create( - project=obj.project, user=user, defaults={"notify_level": NotifyLevel.watch}) + project=obj.project, user=user, defaults={"notify_level": NotifyLevel.all}) return watched @@ -434,7 +434,7 @@ def set_notify_policy_level_to_ignore(notify_policy): """ Set notification level for specified policy. """ - set_notify_policy_level(notify_policy, NotifyLevel.ignore) + set_notify_policy_level(notify_policy, NotifyLevel.none) def make_ms_thread_index(msg_id, dt): diff --git a/taiga/projects/notifications/utils.py b/taiga/projects/notifications/utils.py index 3df08851..49aea78d 100644 --- a/taiga/projects/notifications/utils.py +++ b/taiga/projects/notifications/utils.py @@ -104,7 +104,7 @@ def attach_project_is_watcher_to_queryset(queryset, user, as_field="is_watcher") THEN TRUE ELSE FALSE END""") - sql = sql.format(tbl=model._meta.db_table, user_id=user.id, ignore_notify_level=NotifyLevel.ignore) + sql = sql.format(tbl=model._meta.db_table, user_id=user.id, ignore_notify_level=NotifyLevel.none) qs = queryset.extra(select={as_field: sql}) return qs @@ -124,7 +124,7 @@ def attach_project_total_watchers_attrs_to_queryset(queryset, as_field="total_wa FROM notifications_notifypolicy WHERE notifications_notifypolicy.project_id = {tbl}.id AND notifications_notifypolicy.notify_level != {ignore_notify_level}""") - sql = sql.format(tbl=model._meta.db_table, ignore_notify_level=NotifyLevel.ignore) + sql = sql.format(tbl=model._meta.db_table, ignore_notify_level=NotifyLevel.none) qs = queryset.extra(select={as_field: sql}) return qs @@ -142,7 +142,7 @@ def attach_notify_level_to_project_queryset(queryset, user): :return: Queryset object with the additional `as_field` field. """ user_id = getattr(user, "id", None) or "NULL" - default_level = NotifyLevel.notwatch + default_level = NotifyLevel.involved sql = strip_lines(""" COALESCE((SELECT notifications_notifypolicy.notify_level diff --git a/taiga/users/services.py b/taiga/users/services.py index aea50ca4..93707737 100644 --- a/taiga/users/services.py +++ b/taiga/users/services.py @@ -218,7 +218,7 @@ def _build_watched_sql_for_projects(for_user): ON (projects_project.id = notifications_notifypolicy.project_id) LEFT JOIN (SELECT project_id, count(*) watchers FROM notifications_notifypolicy - WHERE notifications_notifypolicy.notify_level != {ignore_notify_level} + WHERE notifications_notifypolicy.notify_level != {none_notify_level} GROUP BY project_id ) type_watchers ON projects_project.id = type_watchers.project_id @@ -226,11 +226,11 @@ def _build_watched_sql_for_projects(for_user): ON (projects_project.id = likes_likes.object_id AND {project_content_type_id} = likes_likes.content_type_id) WHERE notifications_notifypolicy.user_id = {for_user_id} - AND notifications_notifypolicy.notify_level != {ignore_notify_level} + AND notifications_notifypolicy.notify_level != {none_notify_level} """ sql = sql.format( for_user_id=for_user.id, - ignore_notify_level=NotifyLevel.ignore, + none_notify_level=NotifyLevel.none, project_content_type_id=ContentType.objects.get(app_label="projects", model="project").id) return sql @@ -248,7 +248,7 @@ def _build_liked_sql_for_projects(for_user): ON (projects_project.id = likes_like.object_id) LEFT JOIN (SELECT project_id, count(*) watchers FROM notifications_notifypolicy - WHERE notifications_notifypolicy.notify_level != {ignore_notify_level} + WHERE notifications_notifypolicy.notify_level != {none_notify_level} GROUP BY project_id ) type_watchers ON projects_project.id = type_watchers.project_id @@ -258,7 +258,7 @@ def _build_liked_sql_for_projects(for_user): """ sql = sql.format( for_user_id=for_user.id, - ignore_notify_level=NotifyLevel.ignore, + none_notify_level=NotifyLevel.none, project_content_type_id=ContentType.objects.get(app_label="projects", model="project").id) return sql diff --git a/tests/integration/test_hooks_bitbucket.py b/tests/integration/test_hooks_bitbucket.py index 27cf34db..bef9330f 100644 --- a/tests/integration/test_hooks_bitbucket.py +++ b/tests/integration/test_hooks_bitbucket.py @@ -265,7 +265,7 @@ def test_issues_event_opened_issue(client): issue.project.save() Membership.objects.create(user=issue.owner, project=issue.project, role=f.RoleFactory.create(project=issue.project), is_owner=True) notify_policy = NotifyPolicy.objects.get(user=issue.owner, project=issue.project) - notify_policy.notify_level = NotifyLevel.watch + notify_policy.notify_level = NotifyLevel.all notify_policy.save() payload = { diff --git a/tests/integration/test_hooks_github.py b/tests/integration/test_hooks_github.py index 7017620f..5b832643 100644 --- a/tests/integration/test_hooks_github.py +++ b/tests/integration/test_hooks_github.py @@ -243,7 +243,7 @@ def test_issues_event_opened_issue(client): issue.project.save() Membership.objects.create(user=issue.owner, project=issue.project, role=f.RoleFactory.create(project=issue.project), is_owner=True) notify_policy = NotifyPolicy.objects.get(user=issue.owner, project=issue.project) - notify_policy.notify_level = NotifyLevel.watch + notify_policy.notify_level = NotifyLevel.all notify_policy.save() payload = { diff --git a/tests/integration/test_hooks_gitlab.py b/tests/integration/test_hooks_gitlab.py index eac03668..7264b2c1 100644 --- a/tests/integration/test_hooks_gitlab.py +++ b/tests/integration/test_hooks_gitlab.py @@ -309,7 +309,7 @@ def test_issues_event_opened_issue(client): issue.project.save() Membership.objects.create(user=issue.owner, project=issue.project, role=f.RoleFactory.create(project=issue.project), is_owner=True) notify_policy = NotifyPolicy.objects.get(user=issue.owner, project=issue.project) - notify_policy.notify_level = NotifyLevel.watch + notify_policy.notify_level = NotifyLevel.all notify_policy.save() payload = { diff --git a/tests/integration/test_notifications.py b/tests/integration/test_notifications.py index 4fafc80b..3173874f 100644 --- a/tests/integration/test_notifications.py +++ b/tests/integration/test_notifications.py @@ -60,14 +60,14 @@ def test_attach_notify_level_to_project_queryset(): qs = utils.attach_notify_level_to_project_queryset(qs, project1.owner) assert len(qs) == 2 - assert qs[0].notify_level == NotifyLevel.notwatch - assert qs[1].notify_level == NotifyLevel.notwatch + assert qs[0].notify_level == NotifyLevel.involved + assert qs[1].notify_level == NotifyLevel.involved - services.create_notify_policy(project1, project1.owner, NotifyLevel.watch) + services.create_notify_policy(project1, project1.owner, NotifyLevel.all) qs = project1.__class__.objects.order_by("id") qs = utils.attach_notify_level_to_project_queryset(qs, project1.owner) - assert qs[0].notify_level == NotifyLevel.watch - assert qs[1].notify_level == NotifyLevel.notwatch + assert qs[0].notify_level == NotifyLevel.all + assert qs[1].notify_level == NotifyLevel.involved def test_create_retrieve_notify_policy(): @@ -81,14 +81,14 @@ def test_create_retrieve_notify_policy(): current_number = policy_model_cls.objects.all().count() assert current_number == 1 - assert policy.notify_level == NotifyLevel.notwatch + assert policy.notify_level == NotifyLevel.involved def test_notify_policy_existence(): project = f.ProjectFactory.create() assert not services.notify_policy_exists(project, project.owner) - services.create_notify_policy(project, project.owner, NotifyLevel.watch) + services.create_notify_policy(project, project.owner, NotifyLevel.all) assert services.notify_policy_exists(project, project.owner) @@ -145,23 +145,23 @@ def test_users_to_notify(): member1 = f.MembershipFactory.create(project=project, role=role1) policy_member1 = member1.user.notify_policies.get(project=project) - policy_member1.notify_level = NotifyLevel.ignore + policy_member1.notify_level = NotifyLevel.none policy_member1.save() member2 = f.MembershipFactory.create(project=project, role=role1) policy_member2 = member2.user.notify_policies.get(project=project) - policy_member2.notify_level = NotifyLevel.ignore + policy_member2.notify_level = NotifyLevel.none policy_member2.save() member3 = f.MembershipFactory.create(project=project, role=role1) policy_member3 = member3.user.notify_policies.get(project=project) - policy_member3.notify_level = NotifyLevel.ignore + policy_member3.notify_level = NotifyLevel.none policy_member3.save() member4 = f.MembershipFactory.create(project=project, role=role1) policy_member4 = member4.user.notify_policies.get(project=project) - policy_member4.notify_level = NotifyLevel.ignore + policy_member4.notify_level = NotifyLevel.none policy_member4.save() member5 = f.MembershipFactory.create(project=project, role=role2) policy_member5 = member5.user.notify_policies.get(project=project) - policy_member5.notify_level = NotifyLevel.ignore + policy_member5.notify_level = NotifyLevel.none policy_member5.save() inactive_member1 = f.MembershipFactory.create(project=project, role=role1) inactive_member1.user.is_active = False @@ -175,11 +175,11 @@ def test_users_to_notify(): policy_model_cls = apps.get_model("notifications", "NotifyPolicy") policy_inactive_member1 = policy_model_cls.objects.get(user=inactive_member1.user) - policy_inactive_member1.notify_level = NotifyLevel.watch + policy_inactive_member1.notify_level = NotifyLevel.all policy_inactive_member1.save() policy_system_member1 = policy_model_cls.objects.get(user=system_member1.user) - policy_system_member1.notify_level = NotifyLevel.watch + policy_system_member1.notify_level = NotifyLevel.all policy_system_member1.save() history = MagicMock() @@ -189,14 +189,14 @@ def test_users_to_notify(): # Test basic description modifications issue.description = "test1" issue.save() - policy_member4.notify_level = NotifyLevel.watch + policy_member4.notify_level = NotifyLevel.all policy_member4.save() users = services.get_users_to_notify(issue) assert len(users) == 1 assert tuple(users)[0] == issue.get_owner() # Test watch notify level in one member - policy_member1.notify_level = NotifyLevel.watch + policy_member1.notify_level = NotifyLevel.all policy_member1.save() users = services.get_users_to_notify(issue) @@ -205,14 +205,14 @@ def test_users_to_notify(): # Test with watchers issue.add_watcher(member3.user) - policy_member3.notify_level = NotifyLevel.watch + policy_member3.notify_level = NotifyLevel.all policy_member3.save() users = services.get_users_to_notify(issue) assert len(users) == 3 assert users == {member1.user, member3.user, issue.get_owner()} # Test with watchers with ignore policy - policy_member3.notify_level = NotifyLevel.ignore + policy_member3.notify_level = NotifyLevel.none policy_member3.save() issue.add_watcher(member3.user) @@ -251,7 +251,7 @@ def test_watching_users_to_notify_on_issue_modification_1(): watching_user_policy = services.get_notify_policy(project, watching_user) issue.description = "test1" issue.save() - watching_user_policy.notify_level = NotifyLevel.watch + watching_user_policy.notify_level = NotifyLevel.all users = services.get_users_to_notify(issue) assert users == {watching_user, issue.owner} @@ -260,7 +260,7 @@ def test_watching_users_to_notify_on_issue_modification_2(): # If: # - the user is watching the issue # - the user is not watching the project - # - the notify policy is notwatch + # - the notify policy is involved # Then: # - email is sent project = f.ProjectFactory.create(anon_permissions= ["view_issues"]) @@ -270,7 +270,7 @@ def test_watching_users_to_notify_on_issue_modification_2(): watching_user_policy = services.get_notify_policy(project, watching_user) issue.description = "test1" issue.save() - watching_user_policy.notify_level = NotifyLevel.notwatch + watching_user_policy.notify_level = NotifyLevel.involved users = services.get_users_to_notify(issue) assert users == {watching_user, issue.owner} @@ -289,7 +289,7 @@ def test_watching_users_to_notify_on_issue_modification_3(): watching_user_policy = services.get_notify_policy(project, watching_user) issue.description = "test1" issue.save() - watching_user_policy.notify_level = NotifyLevel.ignore + watching_user_policy.notify_level = NotifyLevel.none watching_user_policy.save() users = services.get_users_to_notify(issue) assert users == {issue.owner} @@ -309,7 +309,7 @@ def test_watching_users_to_notify_on_issue_modification_4(): watching_user_policy = services.get_notify_policy(project, watching_user) issue.description = "test1" issue.save() - watching_user_policy.notify_level = NotifyLevel.ignore + watching_user_policy.notify_level = NotifyLevel.none watching_user_policy.save() users = services.get_users_to_notify(issue) assert users == {issue.owner} @@ -329,7 +329,7 @@ def test_watching_users_to_notify_on_issue_modification_5(): watching_user_policy = services.get_notify_policy(project, watching_user) issue.description = "test1" issue.save() - watching_user_policy.notify_level = NotifyLevel.watch + watching_user_policy.notify_level = NotifyLevel.all watching_user_policy.save() users = services.get_users_to_notify(issue) assert users == {watching_user, issue.owner} @@ -339,7 +339,7 @@ def test_watching_users_to_notify_on_issue_modification_6(): # If: # - the user is not watching the issue # - the user is watching the project - # - the notify policy is notwatch + # - the notify policy is involved # Then: # - email is sent project = f.ProjectFactory.create(anon_permissions= ["view_issues"]) @@ -349,7 +349,7 @@ def test_watching_users_to_notify_on_issue_modification_6(): watching_user_policy = services.get_notify_policy(project, watching_user) issue.description = "test1" issue.save() - watching_user_policy.notify_level = NotifyLevel.notwatch + watching_user_policy.notify_level = NotifyLevel.involved watching_user_policy.save() users = services.get_users_to_notify(issue) assert users == {watching_user, issue.owner} diff --git a/tests/integration/test_users.py b/tests/integration/test_users.py index d9990d45..3b435f0a 100644 --- a/tests/integration/test_users.py +++ b/tests/integration/test_users.py @@ -481,7 +481,7 @@ def test_get_watched_list_for_project_with_ignored_notify_level(): role = f.RoleFactory(project=project, permissions=["view_project", "view_us", "view_tasks", "view_issues"]) membership = f.MembershipFactory(project=project, role=role, user=fav_user) notify_policy = NotifyPolicy.objects.get(user=fav_user, project=project) - notify_policy.notify_level=NotifyLevel.ignore + notify_policy.notify_level=NotifyLevel.none notify_policy.save() watched_list = get_watched_list(fav_user, viewer_user)