def test_developer_reply(self, send_mail_mock):
        # One from the reviewer.
        self._create(amo.LOG.REJECT_VERSION, self.reviewer)
        # One from the developer.  So the developer is on the 'thread'
        self._create(amo.LOG.DEVELOPER_REPLY_VERSION, self.developer)
        action = amo.LOG.DEVELOPER_REPLY_VERSION
        comments = u'Thïs is á reply'
        log_and_notify(action, comments, self.developer, self.version)

        logs = ActivityLog.objects.filter(action=action.id)
        assert len(logs) == 2  # We added one above.
        assert logs[0].details['comments'] == u'Thïs is á reply'

        assert send_mail_mock.call_count == 2  # One author, one reviewer.
        recipients = self._recipients(send_mail_mock)
        assert len(recipients) == 2
        assert self.reviewer.email in recipients
        assert self.developer2.email in recipients
        # The developer who sent it doesn't get their email back.
        assert self.developer.email not in recipients

        self._check_email(send_mail_mock.call_args_list[0],
                          absolutify(self.addon.get_dev_url('versions')),
                          'Developer Reply',
                          'you are an author of this add-on.')
        review_url = absolutify(
            reverse('editors.review',
                    kwargs={
                        'addon_id': self.version.addon.pk,
                        'channel': 'listed'
                    },
                    add_prefix=False))
        self._check_email(send_mail_mock.call_args_list[1], review_url,
                          'Developer Reply', 'you reviewed this add-on.')
Exemple #2
0
    def test_staff_cc_group_get_mail(self, send_mail_mock):
        self.grant_permission(self.reviewer, 'None:None', ACTIVITY_MAIL_GROUP)
        action = amo.LOG.DEVELOPER_REPLY_VERSION
        comments = u'Thïs is á reply'
        log_and_notify(action, comments, self.developer, self.version)

        logs = ActivityLog.objects.filter(action=action.id)
        assert len(logs) == 1

        recipients = self._recipients(send_mail_mock)
        sender = formataddr(
            (self.developer.name, NOTIFICATIONS_FROM_EMAIL))
        assert sender == send_mail_mock.call_args_list[0][1]['from_email']
        assert len(recipients) == 2
        # self.reviewers wasn't on the thread, but gets an email anyway.
        assert self.reviewer.email in recipients
        assert self.developer2.email in recipients
        review_url = absolutify(
            reverse('reviewers.review',
                    kwargs={'addon_id': self.version.addon.pk,
                            'channel': 'listed'},
                    add_prefix=False))
        self._check_email(send_mail_mock.call_args_list[1],
                          review_url,
                          'you are member of the activity email cc group.')
Exemple #3
0
    def test_review_url_unlisted(self, send_mail_mock):
        self.version.update(channel=amo.RELEASE_CHANNEL_UNLISTED)
        self.grant_permission(self.reviewer, 'Addons:ReviewUnlisted',
                              'Addon Reviewers')

        # One from the reviewer.
        self._create(amo.LOG.COMMENT_VERSION, self.reviewer)
        # One from the developer.  So the developer is on the 'thread'
        self._create(amo.LOG.DEVELOPER_REPLY_VERSION, self.developer)
        action = amo.LOG.DEVELOPER_REPLY_VERSION
        comments = u'Thïs is á reply'
        log_and_notify(action, comments, self.developer, self.version)

        logs = ActivityLog.objects.filter(action=action.id)
        assert len(logs) == 2  # We added one above.
        assert logs[0].details['comments'] == u'Thïs is á reply'

        assert send_mail_mock.call_count == 2  # One author, one reviewer.
        recipients = self._recipients(send_mail_mock)

        assert len(recipients) == 2
        assert self.reviewer.email in recipients
        assert self.developer2.email in recipients
        # The developer who sent it doesn't get their email back.
        assert self.developer.email not in recipients

        self._check_email(send_mail_mock.call_args_list[0],
                          absolutify(self.addon.get_dev_url('versions')),
                          'you are listed as an author of this add-on.')
        review_url = absolutify(
            reverse('reviewers.review', add_prefix=False,
                    kwargs={'channel': 'unlisted', 'addon_id': self.addon.pk}))
        self._check_email(send_mail_mock.call_args_list[1],
                          review_url, 'you reviewed this add-on.')
Exemple #4
0
    def test_log_with_no_comment(self, send_mail_mock):
        # One from the reviewer.
        self._create(amo.LOG.REJECT_VERSION, self.reviewer)
        action = amo.LOG.APPROVAL_NOTES_CHANGED
        log_and_notify(
            action=action, comments=None, note_creator=self.developer,
            version=self.version)

        logs = ActivityLog.objects.filter(action=action.id)
        assert len(logs) == 1
        assert not logs[0].details  # No details json because no comment.

        assert send_mail_mock.call_count == 2  # One author, one reviewer.
        sender = formataddr(
            (self.developer.name, NOTIFICATIONS_FROM_EMAIL))
        assert sender == send_mail_mock.call_args_list[0][1]['from_email']
        recipients = self._recipients(send_mail_mock)
        assert len(recipients) == 2
        assert self.reviewer.email in recipients
        assert self.developer2.email in recipients

        assert u'Approval notes changed' in (
            send_mail_mock.call_args_list[0][0][1])
        assert u'Approval notes changed' in (
            send_mail_mock.call_args_list[1][0][1])
Exemple #5
0
    def test_reviewer_reply(self, send_mail_mock):
        # One from the reviewer.
        self._create(amo.LOG.REJECT_VERSION, self.reviewer)
        # One from the developer.
        self._create(amo.LOG.DEVELOPER_REPLY_VERSION, self.developer)
        action = amo.LOG.REVIEWER_REPLY_VERSION
        comments = u'Thîs ïs a revïewer replyîng'
        log_and_notify(action, comments, self.reviewer, self.version)

        logs = ActivityLog.objects.filter(action=action.id)
        assert len(logs) == 1
        assert logs[0].details['comments'] == u'Thîs ïs a revïewer replyîng'

        assert send_mail_mock.call_count == 2  # Both authors.
        sender = formataddr(
            (self.reviewer.reviewer_name, NOTIFICATIONS_FROM_EMAIL))
        assert sender == send_mail_mock.call_args_list[0][1]['from_email']
        recipients = self._recipients(send_mail_mock)
        assert len(recipients) == 2
        assert self.developer.email in recipients
        assert self.developer2.email in recipients
        # The reviewer who sent it doesn't get their email back.
        assert self.reviewer.email not in recipients

        self._check_email(
            send_mail_mock.call_args_list[0],
            absolutify(self.addon.get_dev_url('versions')),
            'you are listed as an author of this add-on.')
        self._check_email(
            send_mail_mock.call_args_list[1],
            absolutify(self.addon.get_dev_url('versions')),
            'you are listed as an author of this add-on.')
Exemple #6
0
    def test_mail_needinfo_correct_subject(self, send_mail_mock):
        self.grant_permission(self.reviewer, 'None:None', ACTIVITY_MAIL_GROUP)
        action = amo.LOG.REQUEST_INFORMATION
        comments = u'Thïs is á reply'
        log_and_notify(action, comments, self.developer, self.version)

        logs = ActivityLog.objects.filter(action=action.id)
        assert len(logs) == 1

        recipients = self._recipients(send_mail_mock)
        sender = '%s <notifications@%s>' % (self.developer.name,
                                            settings.INBOUND_EMAIL_DOMAIN)
        assert sender == send_mail_mock.call_args_list[0][1]['from_email']
        developer_subject = send_mail_mock.call_args_list[0][0][0]
        assert developer_subject == (u'Mozilla Add-ons: Action Required for '
                                     '%s %s' %
                                     (self.addon.name, self.version.version))
        reviewer_subject = send_mail_mock.call_args_list[1][0][0]
        assert reviewer_subject == u'Mozilla Add-ons: %s %s' % (
            self.addon.name, self.version.version)
        assert len(recipients) == 2
        # self.reviewers wasn't on the thread, but gets an email anyway.
        assert self.reviewer.email in recipients
        assert self.developer2.email in recipients
        review_url = absolutify(
            reverse('reviewers.review',
                    kwargs={
                        'addon_id': self.version.addon.pk,
                        'channel': 'listed'
                    },
                    add_prefix=False))
        self._check_email(send_mail_mock.call_args_list[1], review_url,
                          'you are member of the activity email cc group.')
    def test_reviewer_request_for_information_far_date(self, send_mail_mock):
        AddonReviewerFlags.objects.create(
            addon=self.addon,
            pending_info_request=datetime.now() + timedelta(days=21))
        self._create(amo.LOG.REQUEST_INFORMATION, self.reviewer)
        log_and_notify(
            amo.LOG.REQUEST_INFORMATION, 'blah', self.reviewer, self.version)

        assert send_mail_mock.call_count == 2  # Both authors.
        sender = '%s <notifications@%s>' % (
            self.reviewer.name, settings.INBOUND_EMAIL_DOMAIN)
        assert sender == send_mail_mock.call_args_list[0][1]['from_email']
        recipients = self._recipients(send_mail_mock)
        assert len(recipients) == 2
        assert self.developer.email in recipients
        assert self.developer2.email in recipients
        # The reviewer who sent it doesn't get their email back.
        assert self.reviewer.email not in recipients

        self._check_email_info_request(
            send_mail_mock.call_args_list[0],
            absolutify(self.addon.get_dev_url('versions')),
            'you are listed as an author of this add-on.',
            '21 days of this notification')
        self._check_email_info_request(
            send_mail_mock.call_args_list[1],
            absolutify(self.addon.get_dev_url('versions')),
            'you are listed as an author of this add-on.',
            '21 days of this notification')
    def test_mail_needinfo_correct_subject(self, send_mail_mock):
        self.grant_permission(self.reviewer, 'None:None', ACTIVITY_MAIL_GROUP)
        action = amo.LOG.REQUEST_INFORMATION
        comments = u'Thïs is á reply'
        log_and_notify(action, comments, self.developer, self.version)

        logs = ActivityLog.objects.filter(action=action.id)
        assert len(logs) == 1

        recipients = self._recipients(send_mail_mock)
        sender = '%s <notifications@%s>' % (
            self.developer.name, settings.INBOUND_EMAIL_DOMAIN)
        assert sender == send_mail_mock.call_args_list[0][1]['from_email']
        developer_subject = send_mail_mock.call_args_list[0][0][0]
        assert developer_subject == (
            u'Mozilla Add-ons: Action Required for '
            '%s %s' % (self.addon.name, self.version.version))
        reviewer_subject = send_mail_mock.call_args_list[1][0][0]
        assert reviewer_subject == u'Mozilla Add-ons: %s %s' % (
            self.addon.name, self.version.version)
        assert len(recipients) == 2
        # self.reviewers wasn't on the thread, but gets an email anyway.
        assert self.reviewer.email in recipients
        assert self.developer2.email in recipients
        review_url = absolutify(
            reverse('reviewers.review',
                    kwargs={'addon_id': self.version.addon.pk,
                            'channel': 'listed'},
                    add_prefix=False))
        self._check_email(send_mail_mock.call_args_list[1],
                          review_url,
                          'you are member of the activity email cc group.')
Exemple #9
0
    def test_staff_cc_group_get_mail(self, send_mail_mock):
        self.grant_permission(self.reviewer, 'None:None', ACTIVITY_MAIL_GROUP)
        action = amo.LOG.DEVELOPER_REPLY_VERSION
        comments = u'Thïs is á reply'
        log_and_notify(action, comments, self.developer, self.version)

        logs = ActivityLog.objects.filter(action=action.id)
        assert len(logs) == 1

        recipients = self._recipients(send_mail_mock)
        sender = '%s <notifications@%s>' % (
            self.developer.name, settings.INBOUND_EMAIL_DOMAIN)
        assert sender == send_mail_mock.call_args_list[0][1]['from_email']
        assert len(recipients) == 2
        # self.reviewers wasn't on the thread, but gets an email anyway.
        assert self.reviewer.email in recipients
        assert self.developer2.email in recipients
        review_url = absolutify(
            reverse('reviewers.review',
                    kwargs={'addon_id': self.version.addon.pk,
                            'channel': 'listed'},
                    add_prefix=False))
        self._check_email(send_mail_mock.call_args_list[1],
                          review_url,
                          'you are member of the activity email cc group.')
Exemple #10
0
    def test_log_with_no_comment(self, send_mail_mock):
        # One from the reviewer.
        self._create(amo.LOG.REJECT_VERSION, self.reviewer)
        action = amo.LOG.APPROVAL_NOTES_CHANGED
        log_and_notify(
            action=action, comments=None, note_creator=self.developer,
            version=self.version)

        logs = ActivityLog.objects.filter(action=action.id)
        assert len(logs) == 1
        assert not logs[0].details  # No details json because no comment.

        assert send_mail_mock.call_count == 2  # One author, one reviewer.
        sender = '%s <notifications@%s>' % (
            self.developer.name, settings.INBOUND_EMAIL_DOMAIN)
        assert sender == send_mail_mock.call_args_list[0][1]['from_email']
        recipients = self._recipients(send_mail_mock)
        assert len(recipients) == 2
        assert self.reviewer.email in recipients
        assert self.developer2.email in recipients

        assert u'Approval notes changed' in (
            send_mail_mock.call_args_list[0][0][1])
        assert u'Approval notes changed' in (
            send_mail_mock.call_args_list[1][0][1])
Exemple #11
0
    def reviewer_reply(self):
        # Default to reviewer reply action.
        action = amo.LOG.REVIEWER_REPLY_VERSION
        if self.version:
            kw = {}
            info_request = self.data.get('info_request')
            if info_request is not None:
                # Update info request flag.
                kw['has_info_request'] = info_request
                if info_request:
                    # And change action to request info if set
                    action = amo.LOG.REQUEST_INFORMATION
            if (self.version.channel == amo.RELEASE_CHANNEL_UNLISTED
                    and not self.version.reviewed):
                kw['reviewed'] = datetime.datetime.now()
            self.version.update(**kw)

        log.info(u'Sending request for information for %s to authors and other'
                 u'recipients' % self.addon)
        log_and_notify(action,
                       self.data['comments'],
                       self.user,
                       self.version,
                       perm_setting='individual_contact',
                       detail_kwargs={'reviewtype': self.review_type})
Exemple #12
0
    def test_reviewer_request_for_information_far_date(self, send_mail_mock):
        AddonReviewerFlags.objects.create(addon=self.addon,
                                          pending_info_request=datetime.now() +
                                          timedelta(days=21))
        self._create(amo.LOG.REQUEST_INFORMATION, self.reviewer)
        log_and_notify(amo.LOG.REQUEST_INFORMATION, 'blah', self.reviewer,
                       self.version)

        assert send_mail_mock.call_count == 2  # Both authors.
        sender = '%s <notifications@%s>' % (self.reviewer.name,
                                            settings.INBOUND_EMAIL_DOMAIN)
        assert sender == send_mail_mock.call_args_list[0][1]['from_email']
        recipients = self._recipients(send_mail_mock)
        assert len(recipients) == 2
        assert self.developer.email in recipients
        assert self.developer2.email in recipients
        # The reviewer who sent it doesn't get their email back.
        assert self.reviewer.email not in recipients

        self._check_email_info_request(
            send_mail_mock.call_args_list[0],
            absolutify(self.addon.get_dev_url('versions')),
            'you are listed as an author of this add-on.',
            '21 days of this notification')
        self._check_email_info_request(
            send_mail_mock.call_args_list[1],
            absolutify(self.addon.get_dev_url('versions')),
            'you are listed as an author of this add-on.',
            '21 days of this notification')
Exemple #13
0
    def test_reviewer_reply(self, send_mail_mock):
        # One from the reviewer.
        self._create(amo.LOG.REJECT_VERSION, self.reviewer)
        # One from the developer.
        self._create(amo.LOG.DEVELOPER_REPLY_VERSION, self.developer)
        action = amo.LOG.REVIEWER_REPLY_VERSION
        comments = u'Thîs ïs a revïewer replyîng'
        log_and_notify(action, comments, self.reviewer, self.version)

        logs = ActivityLog.objects.filter(action=action.id)
        assert len(logs) == 1
        assert logs[0].details['comments'] == u'Thîs ïs a revïewer replyîng'

        assert send_mail_mock.call_count == 2  # Both authors.
        sender = '%s <notifications@%s>' % (
            self.reviewer.name, settings.INBOUND_EMAIL_DOMAIN)
        assert sender == send_mail_mock.call_args_list[0][1]['from_email']
        recipients = self._recipients(send_mail_mock)
        assert len(recipients) == 2
        assert self.developer.email in recipients
        assert self.developer2.email in recipients
        # The reviewer who sent it doesn't get their email back.
        assert self.reviewer.email not in recipients

        self._check_email(send_mail_mock.call_args_list[0],
                          absolutify(self.addon.get_dev_url('versions')),
                          'you are an author of this add-on.')
        self._check_email(send_mail_mock.call_args_list[1],
                          absolutify(self.addon.get_dev_url('versions')),
                          'you are an author of this add-on.')
Exemple #14
0
    def test_developer_reply(self, send_mail_mock):
        # One from the reviewer.
        self._create(amo.LOG.REJECT_VERSION, self.reviewer)
        # One from the developer.  So the developer is on the 'thread'
        self._create(amo.LOG.DEVELOPER_REPLY_VERSION, self.developer)
        action = amo.LOG.DEVELOPER_REPLY_VERSION
        comments = u'Thïs is á reply'
        log_and_notify(action, comments, self.developer, self.version)

        logs = ActivityLog.objects.filter(action=action.id)
        assert len(logs) == 2  # We added one above.
        assert logs[0].details['comments'] == u'Thïs is á reply'

        assert send_mail_mock.call_count == 2  # One author, one reviewer.
        recipients = self._recipients(send_mail_mock)
        assert len(recipients) == 2
        assert self.reviewer.email in recipients
        assert self.developer2.email in recipients
        # The developer who sent it doesn't get their email back.
        assert self.developer.email not in recipients

        self._check_email(send_mail_mock.call_args_list[0],
                          self.addon.get_dev_url('versions'))
        review_url = absolutify(
            reverse('editors.review', args=[self.addon.pk], add_prefix=False))
        self._check_email(send_mail_mock.call_args_list[1],
                          review_url)
Exemple #15
0
    def test_reviewer_reply(self, send_mail_mock):
        # One from the reviewer.
        self._create(amo.LOG.REJECT_VERSION, self.reviewer)
        # One from the developer.
        self._create(amo.LOG.DEVELOPER_REPLY_VERSION, self.developer)
        action = amo.LOG.REVIEWER_REPLY_VERSION
        comments = u'Thîs ïs a revïewer replyîng'
        log_and_notify(action, comments, self.reviewer, self.version)

        logs = ActivityLog.objects.filter(action=action.id)
        assert len(logs) == 1
        assert logs[0].details['comments'] == u'Thîs ïs a revïewer replyîng'

        assert send_mail_mock.call_count == 2  # Both authors.
        recipients = self._recipients(send_mail_mock)
        assert len(recipients) == 2
        assert self.developer.email in recipients
        assert self.developer2.email in recipients
        # The reviewer who sent it doesn't get their email back.
        assert self.reviewer.email not in recipients

        self._check_email(send_mail_mock.call_args_list[0],
                          self.addon.get_dev_url('versions'))
        self._check_email(send_mail_mock.call_args_list[1],
                          self.addon.get_dev_url('versions'))
Exemple #16
0
    def test_review_url_unlisted(self, send_mail_mock):
        self.version.update(channel=amo.RELEASE_CHANNEL_UNLISTED)
        self.grant_permission(self.reviewer, 'Addons:ReviewUnlisted',
                              'Addon Reviewers')

        # One from the reviewer.
        self._create(amo.LOG.COMMENT_VERSION, self.reviewer)
        # One from the developer.  So the developer is on the 'thread'
        self._create(amo.LOG.DEVELOPER_REPLY_VERSION, self.developer)
        action = amo.LOG.DEVELOPER_REPLY_VERSION
        comments = u'Thïs is á reply'
        log_and_notify(action, comments, self.developer, self.version)

        logs = ActivityLog.objects.filter(action=action.id)
        assert len(logs) == 2  # We added one above.
        assert logs[0].details['comments'] == u'Thïs is á reply'

        assert send_mail_mock.call_count == 2  # One author, one reviewer.
        recipients = self._recipients(send_mail_mock)

        assert len(recipients) == 2
        assert self.reviewer.email in recipients
        assert self.developer2.email in recipients
        # The developer who sent it doesn't get their email back.
        assert self.developer.email not in recipients

        self._check_email(send_mail_mock.call_args_list[0],
                          absolutify(self.addon.get_dev_url('versions')),
                          'you are an author of this add-on.')
        review_url = absolutify(
            reverse('reviewers.review', add_prefix=False,
                    kwargs={'channel': 'unlisted', 'addon_id': self.addon.pk}))
        self._check_email(send_mail_mock.call_args_list[1],
                          review_url, 'you reviewed this add-on.')
Exemple #17
0
    def test_comment_entity_decode(self, send_mail_mock):
        # One from the reviewer.
        self._create(amo.LOG.REJECT_VERSION, self.reviewer)
        action = amo.LOG.REVIEWER_REPLY_VERSION
        comments = f'This email{SQUOTE_ESCAPED}s entities should be decoded'
        log_and_notify(action, comments, self.reviewer, self.version)

        body = send_mail_mock.call_args_list[1][0][1]
        assert "email's entities should be decoded" in body
        assert '&' not in body
    def test_comment_entity_decode(self, send_mail_mock):
        # One from the reviewer.
        self._create(amo.LOG.REJECT_VERSION, self.reviewer)
        action = amo.LOG.REVIEWER_REPLY_VERSION
        comments = u'This email&#39;s entities should be decoded'
        log_and_notify(action, comments, self.reviewer, self.version)

        body = send_mail_mock.call_args_list[1][0][1]
        assert "email's entities should be decoded" in body
        assert "&" not in body
Exemple #19
0
 def save(self, *args, **kwargs):
     super(VersionForm, self).save(*args, **kwargs)
     # Clear pending info request on the addon if requested, adding an entry
     # in the Activity Log to indicate that.
     if self.cleaned_data.get('clear_pending_info_request'):
         AddonReviewerFlags.objects.update_or_create(
             addon=self.instance.addon,
             defaults={'pending_info_request': None})
         log_and_notify(amo.LOG.DEVELOPER_CLEAR_INFO_REQUEST, None,
                        self.request.user, self.instance)
Exemple #20
0
 def save(self, *args, **kwargs):
     super(VersionForm, self).save(*args, **kwargs)
     # Clear pending info request on the addon if requested, adding an entry
     # in the Activity Log to indicate that.
     if self.cleaned_data.get('clear_pending_info_request'):
         AddonReviewerFlags.objects.update_or_create(
             addon=self.instance.addon,
             defaults={'pending_info_request': None})
         log_and_notify(
             amo.LOG.DEVELOPER_CLEAR_INFO_REQUEST, None,
             self.request.user, self.instance)
Exemple #21
0
    def test_from_name_escape(self, send_mail_mock):
        self.reviewer.update(display_name='mr "quote" escape')

        # One from the reviewer.
        self._create(amo.LOG.REJECT_VERSION, self.reviewer)
        action = amo.LOG.REVIEWER_REPLY_VERSION
        comments = u'Thîs ïs a revïewer replyîng'
        log_and_notify(action, comments, self.reviewer, self.version)

        sender = r'"mr \"quote\" escape" <notifications@%s>' % (
            settings.INBOUND_EMAIL_DOMAIN)
        assert sender == send_mail_mock.call_args_list[0][1]['from_email']
Exemple #22
0
    def test_from_name_escape(self, send_mail_mock):
        self.reviewer.update(reviewer_name='mr "quote" escape')

        # One from the reviewer.
        self._create(amo.LOG.REJECT_VERSION, self.reviewer)
        action = amo.LOG.REVIEWER_REPLY_VERSION
        comments = 'Thîs ïs a revïewer replyîng'
        log_and_notify(action, comments, self.reviewer, self.version)

        sender = r'"mr \"quote\" escape" <notifications@%s>' % (
            settings.INBOUND_EMAIL_DOMAIN)
        assert sender == send_mail_mock.call_args_list[0][1]['from_email']
Exemple #23
0
 def _update_admin_review_flag_and_logging(self, version):
     if version.source and not version.addon.needs_admin_code_review:
         AddonReviewerFlags.objects.update_or_create(
             addon=version.addon,
             defaults={'needs_admin_code_review': True})
         # Add Activity Log, notifying staff, relevant reviewers and other authors of
         # the add-on.
         log_and_notify(
             amo.LOG.SOURCE_CODE_UPLOADED,
             None,
             self.context['request'].user,
             version,
         )
Exemple #24
0
    def test_staff_cc_group_get_mail(self, send_mail_mock):
        self.grant_permission(self.reviewer, 'None:None', ACTIVITY_MAIL_GROUP)
        action = amo.LOG.DEVELOPER_REPLY_VERSION
        comments = u'Thïs is á reply'
        log_and_notify(action, comments, self.developer, self.version)

        logs = ActivityLog.objects.filter(action=action.id)
        assert len(logs) == 1

        recipients = self._recipients(send_mail_mock)
        assert len(recipients) == 2
        # self.reviewers wasn't on the thread, but gets an email anyway.
        assert self.reviewer.email in recipients
        assert self.developer2.email in recipients
Exemple #25
0
    def reviewer_reply(self):
        # Default to reviewer reply action.
        action = amo.LOG.REVIEWER_REPLY_VERSION
        if self.version:
            if (self.version.channel == amo.RELEASE_CHANNEL_UNLISTED and
                    not self.version.reviewed):
                self.version.update(reviewed=datetime.now())

        log.info(u'Sending reviewer reply for %s to authors and other'
                 u'recipients' % self.addon)
        log_and_notify(
            action, self.data['comments'], self.user, self.version,
            perm_setting='individual_contact',
            detail_kwargs={'reviewtype': self.review_type.split('_')[1]})
Exemple #26
0
    def test_from_name_escape(self, send_mail_mock):
        self.developer.update(display_name='mr "quote" escape')

        # One from the reviewer.
        self._create(amo.LOG.REJECT_VERSION, self.reviewer)
        # One from the developer.  So the developer is on the 'thread'
        self._create(amo.LOG.DEVELOPER_REPLY_VERSION, self.developer)
        action = amo.LOG.DEVELOPER_REPLY_VERSION
        comments = 'Thïs is á reply'
        log_and_notify(action, comments, self.developer, self.version)

        sender = r'"mr \"quote\" escape" <notifications@%s>' % (
            settings.INBOUND_EMAIL_DOMAIN)
        assert sender == send_mail_mock.call_args_list[0][1]['from_email']
Exemple #27
0
    def test_staff_cc_group_get_mail(self, send_mail_mock):
        self.grant_permission(self.reviewer, 'None:None', ACTIVITY_MAIL_GROUP)
        action = amo.LOG.DEVELOPER_REPLY_VERSION
        comments = u'Thïs is á reply'
        log_and_notify(action, comments, self.developer, self.version)

        logs = ActivityLog.objects.filter(action=action.id)
        assert len(logs) == 1

        recipients = self._recipients(send_mail_mock)
        assert len(recipients) == 2
        # self.reviewers wasn't on the thread, but gets an email anyway.
        assert self.reviewer.email in recipients
        assert self.developer2.email in recipients
Exemple #28
0
    def test_task_user_doesnt_get_mail(self, send_mail_mock):
        """The task user account is used to auto-sign unlisted addons, amongst
        other things, but we don't want that user account to get mail."""
        self._create(amo.LOG.APPROVE_VERSION, self.task_user)

        action = amo.LOG.DEVELOPER_REPLY_VERSION
        comments = 'Thïs is á reply'
        log_and_notify(action, comments, self.developer, self.version)

        logs = ActivityLog.objects.filter(action=action.id)
        assert len(logs) == 1

        recipients = self._recipients(send_mail_mock)
        assert len(recipients) == 1
        assert self.developer2.email in recipients
        assert self.task_user.email not in recipients
    def request_information(self):
        if self.version:
            kw = {'has_info_request': True}
            if (self.version.channel == amo.RELEASE_CHANNEL_UNLISTED
                    and not self.version.reviewed):
                kw['reviewed'] = datetime.datetime.now()
            self.version.update(**kw)

        log.info(u'Sending request for information for %s to authors and other'
                 u'recipients' % self.addon)
        log_and_notify(amo.LOG.REQUEST_INFORMATION,
                       self.data['comments'],
                       self.user,
                       self.version,
                       perm_setting='individual_contact',
                       detail_kwargs={'reviewtype': self.review_type})
Exemple #30
0
    def test_task_user_doesnt_get_mail(self, send_mail_mock):
        """The task user account is used to auto-sign unlisted addons, amongst
        other things, but we don't want that user account to get mail."""
        self._create(amo.LOG.APPROVE_VERSION, self.task_user)

        action = amo.LOG.DEVELOPER_REPLY_VERSION
        comments = u'Thïs is á reply'
        log_and_notify(action, comments, self.developer, self.version)

        logs = ActivityLog.objects.filter(action=action.id)
        assert len(logs) == 1

        recipients = self._recipients(send_mail_mock)
        assert len(recipients) == 1
        assert self.developer2.email in recipients
        assert self.task_user.email not in recipients
Exemple #31
0
    def test_ex_reviewer_doesnt_get_mail(self, send_mail_mock):
        """If a reviewer has now left the team don't email them."""
        self._create(amo.LOG.REJECT_VERSION, self.reviewer)
        # Take his joob!
        GroupUser.objects.get(group=Group.objects.get(name='Addon Reviewers'),
                              user=self.reviewer).delete()

        action = amo.LOG.DEVELOPER_REPLY_VERSION
        comments = u'Thïs is á reply'
        log_and_notify(action, comments, self.developer, self.version)

        logs = ActivityLog.objects.filter(action=action.id)
        assert len(logs) == 1

        recipients = self._recipients(send_mail_mock)
        assert len(recipients) == 1
        assert self.developer2.email in recipients
        assert self.reviewer.email not in recipients
Exemple #32
0
    def test_ex_reviewer_doesnt_get_mail(self, send_mail_mock):
        """If a reviewer has now left the team don't email them."""
        self._create(amo.LOG.REJECT_VERSION, self.reviewer)
        # Take his joob!
        GroupUser.objects.get(group=Group.objects.get(name='Addon Reviewers'),
                              user=self.reviewer).delete()

        action = amo.LOG.DEVELOPER_REPLY_VERSION
        comments = 'Thïs is á reply'
        log_and_notify(action, comments, self.developer, self.version)

        logs = ActivityLog.objects.filter(action=action.id)
        assert len(logs) == 1

        recipients = self._recipients(send_mail_mock)
        assert len(recipients) == 1
        assert self.developer2.email in recipients
        assert self.reviewer.email not in recipients
    def test_developer_reply(self, send_mail_mock):
        # Set pending info request flag to make sure
        # it has been dropped after the reply.
        AddonReviewerFlags.objects.create(
            addon=self.addon,
            pending_info_request=datetime.now() + timedelta(days=1))
        # One from the reviewer.
        self._create(amo.LOG.REJECT_VERSION, self.reviewer)
        # One from the developer.  So the developer is on the 'thread'
        self._create(amo.LOG.DEVELOPER_REPLY_VERSION, self.developer)
        action = amo.LOG.DEVELOPER_REPLY_VERSION
        comments = u'Thïs is á reply'
        log_and_notify(action, comments, self.developer, self.version)

        logs = ActivityLog.objects.filter(action=action.id)
        assert len(logs) == 2  # We added one above.
        assert logs[0].details['comments'] == u'Thïs is á reply'

        assert send_mail_mock.call_count == 2  # One author, one reviewer.
        sender = '%s <notifications@%s>' % (
            self.developer.name, settings.INBOUND_EMAIL_DOMAIN)
        assert sender == send_mail_mock.call_args_list[0][1]['from_email']
        recipients = self._recipients(send_mail_mock)
        assert len(recipients) == 2
        assert self.reviewer.email in recipients
        assert self.developer2.email in recipients
        # The developer who sent it doesn't get their email back.
        assert self.developer.email not in recipients

        self._check_email(
            send_mail_mock.call_args_list[0],
            absolutify(self.addon.get_dev_url('versions')),
            'you are listed as an author of this add-on.')
        review_url = absolutify(
            reverse('reviewers.review',
                    kwargs={'addon_id': self.version.addon.pk,
                            'channel': 'listed'},
                    add_prefix=False))
        self._check_email(
            send_mail_mock.call_args_list[1],
            review_url, 'you reviewed this add-on.')

        self.addon = Addon.objects.get(pk=self.addon.pk)
        assert not self.addon.pending_info_request
Exemple #34
0
    def test_developer_reply(self, send_mail_mock):
        # Set pending info request flag to make sure
        # it has been dropped after the reply.
        AddonReviewerFlags.objects.create(addon=self.addon,
                                          pending_info_request=datetime.now() +
                                          timedelta(days=1))
        # One from the reviewer.
        self._create(amo.LOG.REJECT_VERSION, self.reviewer)
        # One from the developer.  So the developer is on the 'thread'
        self._create(amo.LOG.DEVELOPER_REPLY_VERSION, self.developer)
        action = amo.LOG.DEVELOPER_REPLY_VERSION
        comments = u'Thïs is á reply'
        log_and_notify(action, comments, self.developer, self.version)

        logs = ActivityLog.objects.filter(action=action.id)
        assert len(logs) == 2  # We added one above.
        assert logs[0].details['comments'] == u'Thïs is á reply'

        assert send_mail_mock.call_count == 2  # One author, one reviewer.
        sender = '%s <notifications@%s>' % (self.developer.name,
                                            settings.INBOUND_EMAIL_DOMAIN)
        assert sender == send_mail_mock.call_args_list[0][1]['from_email']
        recipients = self._recipients(send_mail_mock)
        assert len(recipients) == 2
        assert self.reviewer.email in recipients
        assert self.developer2.email in recipients
        # The developer who sent it doesn't get their email back.
        assert self.developer.email not in recipients

        self._check_email(send_mail_mock.call_args_list[0],
                          absolutify(self.addon.get_dev_url('versions')),
                          'you are listed as an author of this add-on.')
        review_url = absolutify(
            reverse('reviewers.review',
                    kwargs={
                        'addon_id': self.version.addon.pk,
                        'channel': 'listed'
                    },
                    add_prefix=False))
        self._check_email(send_mail_mock.call_args_list[1], review_url,
                          'you reviewed this add-on.')

        self.addon = Addon.objects.get(pk=self.addon.pk)
        assert not self.addon.pending_info_request
Exemple #35
0
 def create(self, request, *args, **kwargs):
     version = self.get_version_object()
     if not version == version.addon.latest_or_rejected_version:
         raise ParseError(
             _('Only latest versions of addons can have notes added.'))
     activity_object = log_and_notify(
         action_from_user(request.user, version), request.data['comments'],
         request.user, version)
     serializer = self.get_serializer(activity_object)
     return Response(serializer.data, status=status.HTTP_201_CREATED)
Exemple #36
0
    def reviewer_reply(self):
        # Default to reviewer reply action.
        action = amo.LOG.REVIEWER_REPLY_VERSION
        if self.version:
            if (self.version.channel == amo.RELEASE_CHANNEL_UNLISTED
                    and not self.version.reviewed):
                self.version.update(reviewed=datetime.now())
            if self.data.get('info_request'):
                # It's an information request and not just a simple reply.
                # The ActivityLog will be different...
                action = amo.LOG.REQUEST_INFORMATION
                # And the deadline for the info request will be created or
                # updated x days in the future.
                info_request_deadline_days = int(
                    self.data.get('info_request_deadline',
                                  REVIEWER_NEED_INFO_DAYS_DEFAULT))
                info_request_deadline = (
                    datetime.now() +
                    timedelta(days=info_request_deadline_days))
                # Update or create the reviewer flags, overwriting
                # self.addon.addonreviewerflags with the one we
                # create/update so that we don't use an older version of it
                # later when notifying. Also, since this is a new request,
                # clear out the notified_about_expiring_info_request field.
                self.addon.addonreviewerflags = (
                    AddonReviewerFlags.objects.update_or_create(
                        addon=self.addon,
                        defaults={
                            'pending_info_request': info_request_deadline,
                            'notified_about_expiring_info_request': False,
                        })[0])

        log.info(u'Sending reviewer reply for %s to authors and other'
                 u'recipients' % self.addon)
        log_and_notify(
            action,
            self.data['comments'],
            self.user,
            self.version,
            perm_setting='individual_contact',
            detail_kwargs={'reviewtype': self.review_type.split('_')[1]})
Exemple #37
0
 def create(self, request, *args, **kwargs):
     version = self.get_version_object()
     latest_version = version.addon.find_latest_version(
         channel=version.channel, exclude=())
     if version != latest_version:
         raise ParseError(ugettext(
             'Only latest versions of addons can have notes added.'))
     activity_object = log_and_notify(
         action_from_user(request.user, version), request.data['comments'],
         request.user, version)
     serializer = self.get_serializer(activity_object)
     return Response(serializer.data, status=status.HTTP_201_CREATED)
Exemple #38
0
 def create(self, request, *args, **kwargs):
     version = self.get_version_object()
     latest_version = version.addon.find_latest_version(
         channel=version.channel, exclude=(amo.STATUS_BETA,))
     if version != latest_version:
         raise ParseError(
             _('Only latest versions of addons can have notes added.'))
     activity_object = log_and_notify(
         action_from_user(request.user, version), request.data['comments'],
         request.user, version)
     serializer = self.get_serializer(activity_object)
     return Response(serializer.data, status=status.HTTP_201_CREATED)
Exemple #39
0
    def reviewer_reply(self):
        # Default to reviewer reply action.
        action = amo.LOG.REVIEWER_REPLY_VERSION
        if self.version:
            if (self.version.channel == amo.RELEASE_CHANNEL_UNLISTED and
                    not self.version.reviewed):
                self.version.update(reviewed=datetime.now())
            if self.data.get('info_request'):
                # It's an information request and not just a simple reply.
                # The ActivityLog will be different...
                action = amo.LOG.REQUEST_INFORMATION
                # And the deadline for the info request will be created or
                # updated x days in the future.
                info_request_deadline_days = int(
                    self.data.get('info_request_deadline', 7))
                info_request_deadline = (
                    datetime.now() + timedelta(days=info_request_deadline_days)
                )
                # Update or create the reviewer flags, overwriting
                # self.addon.addonreviewerflags with the one we
                # create/update so that we don't use an older version of it
                # later when notifying. Also, since this is a new request,
                # clear out the notified_about_expiring_info_request field.
                self.addon.addonreviewerflags = (
                    AddonReviewerFlags.objects.update_or_create(
                        addon=self.addon, defaults={
                            'pending_info_request': info_request_deadline,
                            'notified_about_expiring_info_request': False,
                        }
                    )[0]
                )

        log.info(u'Sending reviewer reply for %s to authors and other'
                 u'recipients' % self.addon)
        log_and_notify(action, self.data['comments'],
                       self.user, self.version,
                       perm_setting='individual_contact',
                       detail_kwargs={'reviewtype': self.review_type})
Exemple #40
0
    def reviewer_reply(self):
        # Default to reviewer reply action.
        action = amo.LOG.REVIEWER_REPLY_VERSION
        if self.version:
            kw = {}
            info_request = self.data.get('info_request')
            if info_request is not None:
                # Update info request flag.
                kw['has_info_request'] = info_request
                if info_request:
                    # And change action to request info if set
                    action = amo.LOG.REQUEST_INFORMATION
            if (self.version.channel == amo.RELEASE_CHANNEL_UNLISTED and
                    not self.version.reviewed):
                kw['reviewed'] = datetime.datetime.now()
            self.version.update(**kw)

        log.info(u'Sending request for information for %s to authors and other'
                 u'recipients' % self.addon)
        log_and_notify(action, self.data['comments'],
                       self.user, self.version,
                       perm_setting='individual_contact',
                       detail_kwargs={'reviewtype': self.review_type})
Exemple #41
0
 def test_staff_cc_group_is_empty_no_failure(self):
     Group.objects.create(name=ACTIVITY_MAIL_GROUP, rules='None:None')
     log_and_notify(amo.LOG.REJECT_VERSION, 'á', self.reviewer,
                    self.version)
Exemple #42
0
 def test_staff_cc_group_is_empty_no_failure(self):
     Group.objects.create(name=ACTIVITY_MAIL_GROUP, rules='None:None')
     log_and_notify(amo.LOG.REJECT_VERSION, u'á', self.reviewer,
                    self.version)