Merge pull request #883 from taigaio/issue/4768/Notify-when-something-is-unassigned
Issue 4768: Notify when something is unassignedremotes/origin/issue/4795/notification_even_they_are_disabled
commit
c0daa9180f
|
@ -79,7 +79,7 @@ def create_notify_policy_if_not_exists(project, user, level=NotifyLevel.involved
|
|||
raise exc.IntegrityError(_("Notify exists for specified user and project")) from e
|
||||
|
||||
|
||||
def analize_object_for_watchers(obj:object, comment:str, user:object):
|
||||
def analize_object_for_watchers(obj: object, comment: str, user: object):
|
||||
"""
|
||||
Generic implementation for analize model objects and
|
||||
extract mentions from it and add it to watchers.
|
||||
|
@ -91,7 +91,6 @@ def analize_object_for_watchers(obj:object, comment:str, user:object):
|
|||
if not hasattr(obj, "add_watcher"):
|
||||
return
|
||||
|
||||
|
||||
texts = (getattr(obj, "description", ""),
|
||||
getattr(obj, "content", ""),
|
||||
comment,)
|
||||
|
@ -142,7 +141,7 @@ def get_users_to_notify(obj, *, discard_users=None) -> list:
|
|||
"""
|
||||
project = obj.get_project()
|
||||
|
||||
def _check_level(project:object, user:object, levels:tuple) -> bool:
|
||||
def _check_level(project: object, user: object, levels: tuple) -> bool:
|
||||
policy = project.cached_notify_policy_for_user(user)
|
||||
return policy.notify_level in levels
|
||||
|
||||
|
@ -167,7 +166,7 @@ def get_users_to_notify(obj, *, discard_users=None) -> list:
|
|||
return frozenset(candidates)
|
||||
|
||||
|
||||
def _resolve_template_name(model:object, *, change_type:int) -> str:
|
||||
def _resolve_template_name(model: object, *, change_type: int) -> str:
|
||||
"""
|
||||
Ginven an changed model instance and change type,
|
||||
return the preformated template name for it.
|
||||
|
@ -187,7 +186,7 @@ def _resolve_template_name(model:object, *, change_type:int) -> str:
|
|||
change=change_type)
|
||||
|
||||
|
||||
def _make_template_mail(name:str):
|
||||
def _make_template_mail(name: str):
|
||||
"""
|
||||
Helper that creates a adhoc djmail template email
|
||||
instance for specified name, and return an instance
|
||||
|
@ -211,7 +210,7 @@ def send_notifications(obj, *, history):
|
|||
.get_or_create(key=key,
|
||||
owner=owner,
|
||||
project=obj.project,
|
||||
history_type = history.type))
|
||||
history_type=history.type))
|
||||
|
||||
notification.updated_datetime = timezone.now()
|
||||
notification.save()
|
||||
|
@ -222,6 +221,14 @@ def send_notifications(obj, *, history):
|
|||
notify_users = get_users_to_notify(obj, discard_users=[notification.owner])
|
||||
notification.notify_users.add(*notify_users)
|
||||
|
||||
# If the history is an unassignment change we should notify that user too
|
||||
if history.type == HistoryType.change and "assigned_to" in history.diff:
|
||||
if history.diff["assigned_to"][0] is not None:
|
||||
notification.notify_users.add(history.diff["assigned_to"][0])
|
||||
|
||||
if history.diff["assigned_to"][1] is not None:
|
||||
notification.notify_users.add(history.diff["assigned_to"][1])
|
||||
|
||||
# If we are the min interval is 0 it just work in a synchronous and spamming way
|
||||
if settings.CHANGE_NOTIFICATIONS_MIN_INTERVAL == 0:
|
||||
send_sync_notifications(notification.id)
|
||||
|
@ -392,8 +399,11 @@ def add_watcher(obj, user):
|
|||
:param user: User adding the watch. :class:`~taiga.users.models.User` instance.
|
||||
"""
|
||||
obj_type = apps.get_model("contenttypes", "ContentType").objects.get_for_model(obj)
|
||||
watched, created = Watched.objects.get_or_create(content_type=obj_type,
|
||||
object_id=obj.id, user=user, project=obj.project)
|
||||
watched, created = Watched.objects.get_or_create(
|
||||
content_type=obj_type,
|
||||
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.involved})
|
||||
|
@ -422,7 +432,7 @@ def set_notify_policy_level(notify_policy, notify_level):
|
|||
"""
|
||||
Set notification level for specified policy.
|
||||
"""
|
||||
if not notify_level in [e.value for e in NotifyLevel]:
|
||||
if notify_level not in [e.value for e in NotifyLevel]:
|
||||
raise exc.IntegrityError(_("Invalid value for notify level"))
|
||||
|
||||
notify_policy.notify_level = notify_level
|
||||
|
|
|
@ -726,6 +726,42 @@ def test_send_notifications_using_services_method_for_wiki_pages(settings, mail)
|
|||
assert services.make_ms_thread_index(in_reply_to, msg_ts) == headers.get('Thread-Index')
|
||||
|
||||
|
||||
def test_send_notifications_on_unassigned(client, mail):
|
||||
project = f.ProjectFactory.create()
|
||||
role = f.RoleFactory.create(project=project, permissions=['modify_issue', 'view_issues', 'view_us', 'view_tasks', 'view_wiki_pages'])
|
||||
member1 = f.MembershipFactory.create(project=project, role=role)
|
||||
member2 = f.MembershipFactory.create(project=project, role=role)
|
||||
issue = f.IssueFactory.create(project=project,
|
||||
owner=member1.user,
|
||||
milestone=None,
|
||||
status=project.default_issue_status,
|
||||
severity=project.default_severity,
|
||||
priority=project.default_priority,
|
||||
type=project.default_issue_type)
|
||||
|
||||
take_snapshot(issue, user=issue.owner)
|
||||
|
||||
client.login(member1.user)
|
||||
url = reverse("issues-detail", args=[issue.pk])
|
||||
data = {
|
||||
"assigned_to": member2.user.id,
|
||||
"version": issue.version
|
||||
}
|
||||
response = client.json.patch(url, json.dumps(data))
|
||||
assert len(mail.outbox) == 1
|
||||
assert mail.outbox[0].to == [member2.user.email]
|
||||
|
||||
mail.outbox = []
|
||||
|
||||
data = {
|
||||
"assigned_to": None,
|
||||
"version": issue.version + 1
|
||||
}
|
||||
response = client.json.patch(url, json.dumps(data))
|
||||
assert len(mail.outbox) == 1
|
||||
assert mail.outbox[0].to == [member2.user.email]
|
||||
|
||||
|
||||
def test_resource_notification_test(client, settings, mail):
|
||||
settings.CHANGE_NOTIFICATIONS_MIN_INTERVAL = 1
|
||||
|
||||
|
|
Loading…
Reference in New Issue