示例#1
0
def test_ms_thread_id():
    id = '<test/message@localhost>'
    now = timezone.now()

    index = services.make_ms_thread_index(id, now)
    parsed = parse_ms_thread_index(index)

    assert parsed[0] == hashlib.md5(id.encode('utf-8')).hexdigest()
    # always only one time
    assert (now - parsed[1][0]).seconds <= 2
示例#2
0
def test_ms_thread_id():
    id = '<test/message@localhost>'
    now = timezone.now()

    index = services.make_ms_thread_index(id, now)
    parsed = parse_ms_thread_index(index)

    assert parsed[0] == hashlib.md5(id.encode('utf-8')).hexdigest()
    # always only one time
    assert (now - parsed[1][0]).seconds <= 2
    def send_issue_notification(self, users):
        from taiga.projects.notifications.services import _make_template_mail, make_ms_thread_index
        domain = settings.SITES["api"]["domain"].split(":")[0] or settings.SITES["api"]["domain"]

        issues = Issue.objects.filter(status__is_closed=False)
        projects = Project.objects.filter(issues__in=issues, blocked_code__isnull=True).distinct()

        projects_with_issues = []
        for project in projects:
            url = get_absolute_url('/project/{}/issue'.format(project.slug))
            project_issues = issues.filter(project=project).distinct()
            nr_issues = project_issues.count()
            issue_types = []
            nr_bugs = 0
            for issue_type in project.issue_types.all():
                nr = project_issues.filter(type=issue_type).count()
                if nr:
                    if issue_type.name == 'Bug':
                        nr_bugs = nr
                    issue_types += [{'nr': nr,
                                     'name': issue_type.name,
                                     'color': issue_type.color}]
            projects_with_issues += [{'project': project, 'issues': project_issues, 'nr_bugs': nr_bugs,
                                      'url': url, 'nr_issues': nr_issues, 'issue_types': issue_types}]
        projects_with_issues = sorted(projects_with_issues,
                                      key=lambda project: project['nr_bugs'], reverse=True)
        context = {'projects': projects_with_issues,
                   'summary': "".join([u"- {}: {} ".format(p['project'], p['nr_bugs']) for p in projects_with_issues])}
        
        email = _make_template_mail('issues/issues-list-monthly')

        msg_id = 'taiga-system'
        now = datetime.datetime.now()
        format_args = {
            "project_name": 'taiga-system',
            "project_slug": 'taiga-system',
            "msg_id": msg_id,
            "time": int(now.timestamp()),
            "domain": domain
        }

        headers = {
            "Message-ID": "<{project_slug}/{msg_id}/{time}@{domain}>".format(**format_args),
            "In-Reply-To": "<{project_slug}/{msg_id}@{domain}>".format(**format_args),
            "References": "<{project_slug}/{msg_id}@{domain}>".format(**format_args),
            "List-ID": 'Taiga/{project_name} <taiga.{project_slug}@{domain}>'.format(**format_args),
            "Thread-Index": make_ms_thread_index("<{project_slug}/{msg_id}@{domain}>".format(**format_args), now)
        }

        for user in users:
            context["user"] = user
            context["lang"] = user.lang or settings.LANGUAGE_CODE
            email.send(user.email, context, headers=headers)
    def send_issue_notification(self, users):
        from taiga.projects.notifications.services import _make_template_mail, make_ms_thread_index
        domain = settings.SITES["api"]["domain"].split(":")[0] or settings.SITES["api"]["domain"]

        now = timezone.now()
        time_diff = now - datetime.timedelta(seconds=NOTIFY_ISSUES_TO_SU_INTERVAL)
        issues = Issue.objects.filter(modified_date__gte=time_diff,
                                      status__is_closed=False)
        projects = Project.objects.filter(issues__in=issues).distinct()

        projects_with_issues = []
        for project in projects:
            url = get_absolute_url('/project/{}/issue'.format(project.slug))
            project_issues = issues.filter(project=project).distinct()
            nr_issues = project_issues.count()
            projects_with_issues += [(project, project_issues, url, nr_issues)]
        projects_with_issues = sorted(projects_with_issues, key=lambda project: project[3], reverse=True)
        
        context = {'projects': projects_with_issues,
                   'summary': "".join([u"- {}: {} ".format(p[0], p[3]) for p in projects_with_issues])}
        
        email = _make_template_mail('issues/issues-list')

        msg_id = 'taiga-system'
        now = datetime.datetime.now()
        format_args = {
            "project_name": 'taiga-system',
            "project_slug": 'taiga-system',
            "msg_id": msg_id,
            "time": int(now.timestamp()),
            "domain": domain
        }

        headers = {
            "Message-ID": "<{project_slug}/{msg_id}/{time}@{domain}>".format(**format_args),
            "In-Reply-To": "<{project_slug}/{msg_id}@{domain}>".format(**format_args),
            "References": "<{project_slug}/{msg_id}@{domain}>".format(**format_args),
            "List-ID": 'Taiga/{project_name} <taiga.{project_slug}@{domain}>'.format(**format_args),
            "Thread-Index": make_ms_thread_index("<{project_slug}/{msg_id}@{domain}>".format(**format_args), now)
        }

        for user in users:
            context["user"] = user
            context["lang"] = user.lang or settings.LANGUAGE_CODE
            email.send(user.email, context, headers=headers)
示例#5
0
def test_send_notifications_using_services_method_for_wiki_pages(settings, mail):
    settings.CHANGE_NOTIFICATIONS_MIN_INTERVAL = 1

    project = f.ProjectFactory.create()
    role = f.RoleFactory.create(project=project, permissions=['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)

    wiki = f.WikiPageFactory.create(project=project, owner=member2.user)
    history_change = f.HistoryEntryFactory.create(
        project=project,
        user={"pk": member1.user.id},
        comment="",
        type=HistoryType.change,
        key="wiki.wikipage:{}".format(wiki.id),
        is_hidden=False,
        diff=[]
    )

    history_create = f.HistoryEntryFactory.create(
        project=project,
        user={"pk": member1.user.id},
        comment="",
        type=HistoryType.create,
        key="wiki.wikipage:{}".format(wiki.id),
        is_hidden=False,
        diff=[]
    )

    history_delete = f.HistoryEntryFactory.create(
        project=project,
        user={"pk": member1.user.id},
        comment="test:delete",
        type=HistoryType.delete,
        key="wiki.wikipage:{}".format(wiki.id),
        is_hidden=False,
        diff=[]
    )
    take_snapshot(wiki, user=wiki.owner)
    services.send_notifications(wiki,
                                history=history_create)

    services.send_notifications(wiki,
                                history=history_change)

    services.send_notifications(wiki,
                                history=history_delete)

    assert models.HistoryChangeNotification.objects.count() == 3
    assert len(mail.outbox) == 0
    time.sleep(1)
    services.process_sync_notifications()
    assert len(mail.outbox) == 3

    # test headers
    domain = settings.SITES["api"]["domain"].split(":")[0] or settings.SITES["api"]["domain"]
    for msg in mail.outbox:
        m_id = "{project_slug}/{msg_id}".format(
            project_slug=project.slug,
            msg_id=wiki.slug
        )

        message_id = "<{m_id}/".format(m_id=m_id)
        message_id_domain = "@{domain}>".format(domain=domain)
        in_reply_to = "<{m_id}@{domain}>".format(m_id=m_id, domain=domain)
        list_id = "Taiga/{p_name} <taiga.{p_slug}@{domain}>" \
            .format(p_name=project.name, p_slug=project.slug, domain=domain)

        assert msg.extra_headers
        headers = msg.extra_headers

        # can't test the time part because it's set when sending
        # check what we can
        assert 'Message-ID' in headers
        assert message_id in headers.get('Message-ID')
        assert message_id_domain in headers.get('Message-ID')

        assert 'In-Reply-To' in headers
        assert in_reply_to == headers.get('In-Reply-To')
        assert 'References' in headers
        assert in_reply_to == headers.get('References')

        assert 'List-ID' in headers
        assert list_id == headers.get('List-ID')

        assert 'Thread-Index' in headers

        # hashes should match for identical ids and times
        # we check the actual method in test_ms_thread_id()
        msg_time = headers.get('Message-ID').split('/')[2].split('@')[0]
        msg_ts = datetime.datetime.fromtimestamp(int(msg_time))
        assert services.make_ms_thread_index(in_reply_to, msg_ts) == headers.get('Thread-Index')
示例#6
0
def test_send_notifications_using_services_method_for_wiki_pages(
        settings, mail):
    settings.CHANGE_NOTIFICATIONS_MIN_INTERVAL = 1

    project = f.ProjectFactory.create()
    role = f.RoleFactory.create(project=project,
                                permissions=[
                                    '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)

    wiki = f.WikiPageFactory.create(project=project, owner=member2.user)
    history_change = f.HistoryEntryFactory.create(
        project=project,
        user={"pk": member1.user.id},
        comment="test:change",
        type=HistoryType.change,
        key="wiki.wikipage:{}".format(wiki.id),
        is_hidden=False,
        diff=[])

    history_create = f.HistoryEntryFactory.create(
        project=project,
        user={"pk": member1.user.id},
        comment="",
        type=HistoryType.create,
        key="wiki.wikipage:{}".format(wiki.id),
        is_hidden=False,
        diff=[])

    history_delete = f.HistoryEntryFactory.create(
        project=project,
        user={"pk": member1.user.id},
        comment="test:delete",
        type=HistoryType.delete,
        key="wiki.wikipage:{}".format(wiki.id),
        is_hidden=False,
        diff=[])
    take_snapshot(wiki, user=wiki.owner)
    services.send_notifications(wiki, history=history_create)

    services.send_notifications(wiki, history=history_change)

    services.send_notifications(wiki, history=history_delete)

    assert models.HistoryChangeNotification.objects.count() == 3
    assert len(mail.outbox) == 0
    time.sleep(1)
    services.process_sync_notifications()
    assert len(mail.outbox) == 3

    # test headers
    domain = settings.SITES["api"]["domain"].split(
        ":")[0] or settings.SITES["api"]["domain"]
    for msg in mail.outbox:
        m_id = "{project_slug}/{msg_id}".format(project_slug=project.slug,
                                                msg_id=wiki.slug)

        message_id = "<{m_id}/".format(m_id=m_id)
        message_id_domain = "@{domain}>".format(domain=domain)
        in_reply_to = "<{m_id}@{domain}>".format(m_id=m_id, domain=domain)
        list_id = "Taiga/{p_name} <taiga.{p_slug}@{domain}>" \
            .format(p_name=project.name, p_slug=project.slug, domain=domain)

        assert msg.extra_headers
        headers = msg.extra_headers

        # can't test the time part because it's set when sending
        # check what we can
        assert 'Message-ID' in headers
        assert message_id in headers.get('Message-ID')
        assert message_id_domain in headers.get('Message-ID')

        assert 'In-Reply-To' in headers
        assert in_reply_to == headers.get('In-Reply-To')
        assert 'References' in headers
        assert in_reply_to == headers.get('References')

        assert 'List-ID' in headers
        assert list_id == headers.get('List-ID')

        assert 'Thread-Index' in headers

        # hashes should match for identical ids and times
        # we check the actual method in test_ms_thread_id()
        msg_time = headers.get('Message-ID').split('/')[2].split('@')[0]
        msg_ts = datetime.datetime.fromtimestamp(int(msg_time))
        assert services.make_ms_thread_index(
            in_reply_to, msg_ts) == headers.get('Thread-Index')
示例#7
0
def test_send_notifications_using_services_method(settings, mail):
    settings.CHANGE_NOTIFICATIONS_MIN_INTERVAL = 1

    project = f.ProjectFactory.create()
    role = f.RoleFactory.create(project=project,
                                permissions=[
                                    '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)

    history_change = MagicMock()
    history_change.user = {"pk": member1.user.pk}
    history_change.comment = ""
    history_change.type = HistoryType.change
    history_change.is_hidden = False

    history_create = MagicMock()
    history_create.user = {"pk": member1.user.pk}
    history_create.comment = ""
    history_create.type = HistoryType.create
    history_create.is_hidden = False

    history_delete = MagicMock()
    history_delete.user = {"pk": member1.user.pk}
    history_delete.comment = ""
    history_delete.type = HistoryType.delete
    history_delete.is_hidden = False

    # Issues
    issue = f.IssueFactory.create(project=project, owner=member2.user)
    take_snapshot(issue, user=issue.owner)
    services.send_notifications(issue, history=history_create)

    services.send_notifications(issue, history=history_change)

    services.send_notifications(issue, history=history_delete)

    # Userstories
    us = f.UserStoryFactory.create(project=project, owner=member2.user)
    take_snapshot(us, user=us.owner)
    services.send_notifications(us, history=history_create)

    services.send_notifications(us, history=history_change)

    services.send_notifications(us, history=history_delete)

    # Tasks
    task = f.TaskFactory.create(project=project, owner=member2.user)
    take_snapshot(task, user=task.owner)
    services.send_notifications(task, history=history_create)

    services.send_notifications(task, history=history_change)

    services.send_notifications(task, history=history_delete)

    # Wiki pages
    wiki = f.WikiPageFactory.create(project=project, owner=member2.user)
    take_snapshot(wiki, user=wiki.owner)
    services.send_notifications(wiki, history=history_create)

    services.send_notifications(wiki, history=history_change)

    services.send_notifications(wiki, history=history_delete)

    assert models.HistoryChangeNotification.objects.count() == 12
    assert len(mail.outbox) == 0
    time.sleep(1)
    services.process_sync_notifications()
    assert len(mail.outbox) == 12

    # test headers
    events = [issue, us, task, wiki]
    domain = settings.SITES["api"]["domain"].split(
        ":")[0] or settings.SITES["api"]["domain"]
    i = 0
    for msg in mail.outbox:
        # each event has 3 msgs
        event = events[math.floor(i / 3)]

        # each set of 3 should have the same headers
        if i % 3 == 0:
            if hasattr(event, 'ref'):
                e_slug = event.ref
            elif hasattr(event, 'slug'):
                e_slug = event.slug
            else:
                e_slug = 'taiga-system'

            m_id = "{project_slug}/{msg_id}".format(project_slug=project.slug,
                                                    msg_id=e_slug)

            message_id = "<{m_id}/".format(m_id=m_id)
            message_id_domain = "@{domain}>".format(domain=domain)
            in_reply_to = "<{m_id}@{domain}>".format(m_id=m_id, domain=domain)
            list_id = "Taiga/{p_name} <taiga.{p_slug}@{domain}>" \
                .format(p_name=project.name, p_slug=project.slug, domain=domain)

        assert msg.extra_headers
        headers = msg.extra_headers

        # can't test the time part because it's set when sending
        # check what we can
        assert 'Message-ID' in headers
        assert message_id in headers.get('Message-ID')
        assert message_id_domain in headers.get('Message-ID')

        assert 'In-Reply-To' in headers
        assert in_reply_to == headers.get('In-Reply-To')
        assert 'References' in headers
        assert in_reply_to == headers.get('References')

        assert 'List-ID' in headers
        assert list_id == headers.get('List-ID')

        assert 'Thread-Index' in headers
        # always is b64 encoded 22 bytes
        assert len(base64.b64decode(headers.get('Thread-Index'))) == 22

        # hashes should match for identical ids and times
        # we check the actual method in test_ms_thread_id()
        msg_time = headers.get('Message-ID').split('/')[2].split('@')[0]
        msg_ts = datetime.datetime.fromtimestamp(int(msg_time))
        assert services.make_ms_thread_index(
            in_reply_to, msg_ts) == headers.get('Thread-Index')

        i += 1
示例#8
0
def test_send_notifications_using_services_method(settings, mail):
    settings.CHANGE_NOTIFICATIONS_MIN_INTERVAL = 1

    project = f.ProjectFactory.create()
    role = f.RoleFactory.create(project=project, permissions=['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)

    history_change = MagicMock()
    history_change.user = {"pk": member1.user.pk}
    history_change.comment = ""
    history_change.type = HistoryType.change
    history_change.is_hidden = False

    history_create = MagicMock()
    history_create.user = {"pk": member1.user.pk}
    history_create.comment = ""
    history_create.type = HistoryType.create
    history_create.is_hidden = False

    history_delete = MagicMock()
    history_delete.user = {"pk": member1.user.pk}
    history_delete.comment = ""
    history_delete.type = HistoryType.delete
    history_delete.is_hidden = False

    # Issues
    issue = f.IssueFactory.create(project=project, owner=member2.user)
    take_snapshot(issue, user=issue.owner)
    services.send_notifications(issue,
                                history=history_create)

    services.send_notifications(issue,
                                history=history_change)

    services.send_notifications(issue,
                                history=history_delete)

    # Userstories
    us = f.UserStoryFactory.create(project=project, owner=member2.user)
    take_snapshot(us, user=us.owner)
    services.send_notifications(us,
                                history=history_create)

    services.send_notifications(us,
                                history=history_change)

    services.send_notifications(us,
                                history=history_delete)

    # Tasks
    task = f.TaskFactory.create(project=project, owner=member2.user)
    take_snapshot(task, user=task.owner)
    services.send_notifications(task,
                                history=history_create)

    services.send_notifications(task,
                                history=history_change)

    services.send_notifications(task,
                                history=history_delete)

    # Wiki pages
    wiki = f.WikiPageFactory.create(project=project, owner=member2.user)
    take_snapshot(wiki, user=wiki.owner)
    services.send_notifications(wiki,
                                history=history_create)

    services.send_notifications(wiki,
                                history=history_change)

    services.send_notifications(wiki,
                                history=history_delete)

    assert models.HistoryChangeNotification.objects.count() == 12
    assert len(mail.outbox) == 0
    time.sleep(1)
    services.process_sync_notifications()
    assert len(mail.outbox) == 12

    # test headers
    events = [issue, us, task, wiki]
    domain = settings.SITES["api"]["domain"].split(":")[0] or settings.SITES["api"]["domain"]
    i = 0
    for msg in mail.outbox:
        # each event has 3 msgs
        event = events[math.floor(i / 3)]

        # each set of 3 should have the same headers
        if i % 3 == 0:
            if hasattr(event, 'ref'):
                e_slug = event.ref
            elif hasattr(event, 'slug'):
                e_slug = event.slug
            else:
                e_slug = 'taiga-system'

            m_id = "{project_slug}/{msg_id}".format(
                project_slug=project.slug,
                msg_id=e_slug
            )

            message_id = "<{m_id}/".format(m_id=m_id)
            message_id_domain = "@{domain}>".format(domain=domain)
            in_reply_to = "<{m_id}@{domain}>".format(m_id=m_id, domain=domain)
            list_id = "Taiga/{p_name} <taiga.{p_slug}@{domain}>" \
                .format(p_name=project.name, p_slug=project.slug, domain=domain)

        assert msg.extra_headers
        headers = msg.extra_headers

        # can't test the time part because it's set when sending
        # check what we can
        assert 'Message-ID' in headers
        assert message_id in headers.get('Message-ID')
        assert message_id_domain in headers.get('Message-ID')

        assert 'In-Reply-To' in headers
        assert in_reply_to == headers.get('In-Reply-To')
        assert 'References' in headers
        assert in_reply_to == headers.get('References')

        assert 'List-ID' in headers
        assert list_id == headers.get('List-ID')

        assert 'Thread-Index' in headers
        # always is b64 encoded 22 bytes
        assert len(base64.b64decode(headers.get('Thread-Index'))) == 22

        # hashes should match for identical ids and times
        # we check the actual method in test_ms_thread_id()
        msg_time = headers.get('Message-ID').split('/')[2].split('@')[0]
        msg_ts = datetime.datetime.fromtimestamp(int(msg_time))
        assert services.make_ms_thread_index(in_reply_to, msg_ts) == headers.get('Thread-Index')

        i += 1
def test_send_notifications_using_services_method_for_issues(settings, mail):
    settings.CHANGE_NOTIFICATIONS_MIN_INTERVAL = 1

    project = f.ProjectFactory.create()
    role = f.RoleFactory.create(
        project=project, permissions=["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=member2.user)
    history_change = f.HistoryEntryFactory.create(
        user={"pk": member1.user.id},
        comment="",
        type=HistoryType.change,
        key="issues.issue:{}".format(issue.id),
        is_hidden=False,
        diff=[],
    )

    history_create = f.HistoryEntryFactory.create(
        user={"pk": member1.user.id},
        comment="",
        type=HistoryType.create,
        key="issues.issue:{}".format(issue.id),
        is_hidden=False,
        diff=[],
    )

    history_delete = f.HistoryEntryFactory.create(
        user={"pk": member1.user.id},
        comment="test:delete",
        type=HistoryType.delete,
        key="issues.issue:{}".format(issue.id),
        is_hidden=False,
        diff=[],
    )

    take_snapshot(issue, user=issue.owner)
    services.send_notifications(issue, history=history_create)

    services.send_notifications(issue, history=history_change)

    services.send_notifications(issue, history=history_delete)

    assert models.HistoryChangeNotification.objects.count() == 3
    assert len(mail.outbox) == 0
    time.sleep(1)
    services.process_sync_notifications()
    assert len(mail.outbox) == 3

    # test headers
    domain = settings.SITES["api"]["domain"].split(":")[0] or settings.SITES["api"]["domain"]
    for msg in mail.outbox:
        m_id = "{project_slug}/{msg_id}".format(project_slug=project.slug, msg_id=issue.ref)

        message_id = "<{m_id}/".format(m_id=m_id)
        message_id_domain = "@{domain}>".format(domain=domain)
        in_reply_to = "<{m_id}@{domain}>".format(m_id=m_id, domain=domain)
        list_id = "Taiga/{p_name} <taiga.{p_slug}@{domain}>".format(
            p_name=project.name, p_slug=project.slug, domain=domain
        )

        assert msg.extra_headers
        headers = msg.extra_headers

        # can't test the time part because it's set when sending
        # check what we can
        assert "Message-ID" in headers
        assert message_id in headers.get("Message-ID")
        assert message_id_domain in headers.get("Message-ID")

        assert "In-Reply-To" in headers
        assert in_reply_to == headers.get("In-Reply-To")
        assert "References" in headers
        assert in_reply_to == headers.get("References")

        assert "List-ID" in headers
        assert list_id == headers.get("List-ID")

        assert "Thread-Index" in headers
        # always is b64 encoded 22 bytes
        assert len(base64.b64decode(headers.get("Thread-Index"))) == 22

        # hashes should match for identical ids and times
        # we check the actual method in test_ms_thread_id()
        msg_time = headers.get("Message-ID").split("/")[2].split("@")[0]
        msg_ts = datetime.datetime.fromtimestamp(int(msg_time))
        assert services.make_ms_thread_index(in_reply_to, msg_ts) == headers.get("Thread-Index")