コード例 #1
0
ファイル: test_models.py プロジェクト: Osmose/olympia
 def test_version_log(self):
     version = Version.objects.all()[0]
     ActivityLog.create(amo.LOG.REJECT_VERSION, version.addon, version,
                        user=self.request.user)
     entries = ActivityLog.objects.for_version(version)
     assert len(entries) == 1
     assert version.get_url_path() in unicode(entries[0])
コード例 #2
0
ファイル: test_views_themes.py プロジェクト: Osmose/olympia
    def test_user_review_history(self):
        self.theme_factory()

        reviewer = self.create_and_become_reviewer()

        res = self.client.get(reverse('editors.themes.history'))
        assert res.status_code == 200
        doc = pq(res.content)
        assert doc('tbody tr').length == 0

        theme = Persona.objects.all()[0]
        for x in range(3):
            ActivityLog.create(
                amo.LOG.THEME_REVIEW, theme.addon, user=reviewer,
                details={'action': rvw.ACTION_APPROVE,
                         'comment': '', 'reject_reason': ''})

        res = self.client.get(reverse('editors.themes.history'))
        assert res.status_code == 200
        doc = pq(res.content)
        assert doc('tbody tr').length == 3

        res = self.client.get(reverse('editors.themes.logs'))
        assert res.status_code == 200
        doc = pq(res.content)
        assert doc('tbody tr').length == 3 * 2  # Double for comment rows.
コード例 #3
0
ファイル: test_models.py プロジェクト: Osmose/olympia
 def test_json_failboat(self):
     addon = Addon.objects.get()
     ActivityLog.create(amo.LOG.CREATE_ADDON, addon)
     entry = ActivityLog.objects.get()
     entry._arguments = 'failboat?'
     entry.save()
     assert entry.arguments is None
コード例 #4
0
    def test_normal(self):
        addon = addon_factory()
        author = user_factory(username=u'Authør')
        AddonUser.objects.create(addon=addon, user=author)
        # Add a pending info request expiring soon.
        flags = AddonReviewerFlags.objects.create(
            addon=addon,
            pending_info_request=datetime.now() + timedelta(hours=23),
            notified_about_expiring_info_request=False)
        # Create reviewer and staff users, and create the request for info
        # activity. Neither the reviewer nor the staff user should be cc'ed.
        reviewer = user_factory(username=u'Revièwer')
        self.grant_permission(reviewer, 'Addons:Review')
        ActivityLog.create(
            amo.LOG.REQUEST_INFORMATION, addon, addon.current_version,
            user=reviewer, details={'comments': u'Fly you fôöls!'})
        staff = user_factory(username=u'Staff Ûser')
        self.grant_permission(staff, 'Some:Perm', name=ACTIVITY_MAIL_GROUP)

        # Fire the command.
        call_command('send_info_request_last_warning_notifications')

        assert len(mail.outbox) == 1
        msg = mail.outbox[0]
        assert msg.to == [author.email]
        assert msg.subject == u'Mozilla Add-ons: Action Required for %s %s' % (
            addon.name, addon.current_version.version)
        assert 'an issue when reviewing ' in msg.body
        assert 'within one (1) day' in msg.body

        flags.reload()
        assert flags.notified_about_expiring_info_request is True
コード例 #5
0
ファイル: test_models.py プロジェクト: Osmose/olympia
 def test_addon_logging_pseudo(self):
     """
     If we are given (Addon, 3615) it should log in the AddonLog as well.
     """
     addon = Addon.objects.get()
     ActivityLog.create(amo.LOG.CREATE_ADDON, (Addon, addon.id))
     assert AddonLog.objects.count() == 1
コード例 #6
0
ファイル: test_admin.py プロジェクト: mozilla/addons-server
    def test_last_known_activity_time(self):
        someone_else = user_factory(username='******')
        addon = addon_factory()

        model_admin = UserAdmin(UserProfile, admin.site)
        assert six.text_type(
            model_admin.last_known_activity_time(self.user)) == ''

        # Add various activities. They will be attached to whatever user is
        # set in the thread global at the time, so set that in advance.
        core.set_user(self.user)
        expected_date = self.days_ago(1)
        activity = ActivityLog.create(amo.LOG.CREATE_ADDON, addon)
        activity.update(created=self.days_ago(2))
        activity.userlog_set.update(created=self.days_ago(2))

        activity = ActivityLog.create(amo.LOG.EDIT_PROPERTIES, addon)
        activity.update(created=expected_date)
        activity.userlog_set.update(created=expected_date)

        assert activity.reload().created == expected_date

        # Create another activity, more recent, attached to a different user.
        core.set_user(someone_else)
        activity = ActivityLog.create(amo.LOG.EDIT_PROPERTIES, addon)

        expected_result = DateFormat(expected_date).format(
            settings.DATETIME_FORMAT)

        assert (
            six.text_type(model_admin.last_known_activity_time(self.user)) ==
            expected_result)
コード例 #7
0
ファイル: forms.py プロジェクト: Osmose/olympia
    def save(self, *args, **kw):
        """Save all form data.

        This will only create a new license if it's not one of the builtin
        ones.

        Keyword arguments

        **log=True**
            Set to False if you do not want to log this action for display
            on the developer dashboard.
        """
        log = kw.pop('log', True)
        changed = self.changed_data

        builtin = self.cleaned_data['builtin']
        if builtin == '':  # No license chosen, it must be an unlisted add-on.
            return
        if builtin != License.OTHER:
            # We're dealing with a builtin license, there is no modifications
            # allowed to it, just return it.
            license = License.objects.get(builtin=builtin)
        else:
            # We're not dealing with a builtin license, so save it to the
            # database.
            license = super(LicenseForm, self).save(*args, **kw)

        if self.version:
            if changed or license != self.version.license:
                self.version.update(license=license)
                if log:
                    ActivityLog.create(amo.LOG.CHANGE_LICENSE, license,
                                       self.version.addon)
        return license
コード例 #8
0
ファイル: test_feeds.py プロジェクト: diox/olympia
 def test_hidden(self):
     version = Version.objects.create(addon=self.addon)
     ActivityLog.create(amo.LOG.COMMENT_VERSION, self.addon, version)
     res = self.get_response(addon=self.addon.id)
     key = RssKey.objects.get()
     res = self.get_response(privaterss=key.key)
     assert b'<title>Comment on' not in res.content
コード例 #9
0
ファイル: views.py プロジェクト: bqbn/addons-server
def addon_manage(request, addon):
    form = AddonStatusForm(request.POST or None, instance=addon)
    pager = amo.utils.paginate(
        request, Version.unfiltered.filter(addon=addon), 30)
    # A list coercion so this doesn't result in a subquery with a LIMIT which
    # MySQL doesn't support (at this time).
    versions = list(pager.object_list)
    files = File.objects.filter(version__in=versions).select_related('version')
    formset = FileFormSet(request.POST or None, queryset=files)

    if form.is_valid() and formset.is_valid():
        if 'status' in form.changed_data:
            ActivityLog.create(amo.LOG.CHANGE_STATUS, addon,
                               form.cleaned_data['status'])
            log.info('Addon "%s" status changed to: %s' % (
                addon.slug, form.cleaned_data['status']))
            form.save()

        for form in formset:
            if 'status' in form.changed_data:
                log.info('Addon "%s" file (ID:%d) status changed to: %s' % (
                    addon.slug, form.instance.id, form.cleaned_data['status']))
                form.save()
        return redirect('zadmin.addon_manage', addon.slug)

    # Build a map from file.id to form in formset for precise form display
    form_map = dict((form.instance.id, form) for form in formset.forms)
    # A version to file map to avoid an extra query in the template
    file_map = {}
    for file in files:
        file_map.setdefault(file.version_id, []).append(file)

    return render(request, 'zadmin/addon_manage.html', {
        'addon': addon, 'pager': pager, 'versions': versions, 'form': form,
        'formset': formset, 'form_map': form_map, 'file_map': file_map})
コード例 #10
0
ファイル: forms.py プロジェクト: bqbn/addons-server
    def save(self):
        action = self.cleaned_data['action']
        comment = self.cleaned_data.get('comment')
        reject_reason = self.cleaned_data.get('reject_reason')
        theme = self.cleaned_data['theme']

        is_rereview = (
            theme.rereviewqueuetheme_set.exists() and
            theme.addon.status not in (amo.STATUS_PENDING,
                                       amo.STATUS_REVIEW_PENDING))

        theme_lock = ThemeLock.objects.get(theme=self.cleaned_data['theme'])

        mail_and_log = True
        if action == amo.ACTION_APPROVE:
            if is_rereview:
                approve_rereview(theme)
            theme.addon.update(status=amo.STATUS_PUBLIC)
            theme.approve = datetime.datetime.now()
            theme.save()

        elif action in (amo.ACTION_REJECT, amo.ACTION_DUPLICATE):
            if is_rereview:
                reject_rereview(theme)
            else:
                theme.addon.update(status=amo.STATUS_REJECTED)

        elif action == amo.ACTION_FLAG:
            if is_rereview:
                mail_and_log = False
            else:
                theme.addon.update(status=amo.STATUS_REVIEW_PENDING)

        elif action == amo.ACTION_MOREINFO:
            if not is_rereview:
                theme.addon.update(status=amo.STATUS_REVIEW_PENDING)

        if mail_and_log:
            send_mail(self.cleaned_data, theme_lock)

            # Log.
            ActivityLog.create(
                amo.LOG.THEME_REVIEW, theme.addon, details={
                    'theme': theme.addon.name.localized_string,
                    'action': action,
                    'reject_reason': reject_reason,
                    'comment': comment}, user=theme_lock.reviewer)
            log.info('%sTheme %s (%s) - %s' % (
                '[Rereview] ' if is_rereview else '', theme.addon.name,
                theme.id, action))

        score = 0
        if action in (amo.ACTION_REJECT, amo.ACTION_DUPLICATE,
                      amo.ACTION_APPROVE):
            score = ReviewerScore.award_points(
                theme_lock.reviewer, theme.addon, theme.addon.status)
        theme_lock.delete()

        return score
コード例 #11
0
ファイル: test_models.py プロジェクト: Osmose/olympia
 def test_tag_no_match(self):
     addon = Addon.objects.get()
     tag = Tag.objects.create(tag_text='http://foo.com')
     ActivityLog.create(amo.LOG.ADD_TAG, addon, tag)
     log = ActivityLog.objects.get()
     text = amo.utils.from_string('<p>{{ log }}</p>').render({'log': log})
     # There should only be one a, the link to the addon, but no tag link.
     assert len(pq(text)('a')) == 1
コード例 #12
0
ファイル: views.py プロジェクト: piyushmittal25/addons-server
 def disable(self, request, **kwargs):
     addon = get_object_or_404(Addon, pk=kwargs['pk'])
     ActivityLog.create(amo.LOG.CHANGE_STATUS, addon, amo.STATUS_DISABLED)
     self.log.info('Addon "%s" status changed to: %s',
                   addon.slug, amo.STATUS_DISABLED)
     addon.update(status=amo.STATUS_DISABLED)
     addon.update_version()
     return Response(status=status.HTTP_202_ACCEPTED)
コード例 #13
0
ファイル: test_models.py プロジェクト: Osmose/olympia
 def test_basic(self):
     addon = Addon.objects.get()
     ActivityLog.create(amo.LOG.CREATE_ADDON, addon)
     entries = ActivityLog.objects.for_addons(addon)
     assert len(entries) == 1
     assert entries[0].arguments[0] == addon
     for x in ('Delicious Bookmarks', 'was created.'):
         assert x in unicode(entries[0])
コード例 #14
0
ファイル: forms.py プロジェクト: bqbn/addons-server
    def save(self):
        addon = self.instance
        persona = addon.persona
        data = self.cleaned_data

        # Update Persona-specific data.
        persona_data = {
            'license': int(data['license']),
            'accentcolor': data['accentcolor'].lstrip('#'),
            'textcolor': data['textcolor'].lstrip('#'),
            'author': self.request.user.username,
            'display_username': self.request.user.name
        }
        changed = False
        for k, v in persona_data.iteritems():
            if v != getattr(persona, k):
                changed = True
                setattr(persona, k, v)
        if changed:
            persona.save()

        if self.changed_data:
            ActivityLog.create(amo.LOG.EDIT_PROPERTIES, addon)
        self.instance.modified = datetime.now()

        # Update Addon-specific data.
        changed = (
            set(self.old_tags) != data['tags'] or  # Check if tags changed.
            self.initial['slug'] != data['slug'] or  # Check if slug changed.
            transfield_changed('description', self.initial, data) or
            transfield_changed('name', self.initial, data))
        if changed:
            # Only save if addon data changed.
            super(EditThemeForm, self).save()

        # Update tags.
        tags_new = data['tags']
        tags_old = [slugify(t, spaces=True) for t in self.old_tags]
        # Add new tags.
        for t in set(tags_new) - set(tags_old):
            Tag(tag_text=t).save_tag(addon)
        # Remove old tags.
        for t in set(tags_old) - set(tags_new):
            Tag(tag_text=t).remove_tag(addon)

        # Update category.
        if data['category'].id != self.initial['category']:
            addon_cat = addon.addoncategory_set.all()[0]
            addon_cat.category = data['category']
            addon_cat.save()

        # Theme reupload.
        if not addon.is_pending():
            if data['header_hash']:
                addons_tasks.save_theme_reupload.delay(
                    data['header_hash'], addon.pk)

        return data
コード例 #15
0
ファイル: test_views.py プロジェクト: Osmose/olympia
 def test_we_only_email_devs_that_need_emailing(self):
     # Doesn't matter the reason, but this addon doesn't get an email.
     ActivityLog.create(
         amo.LOG.PRELIMINARY_ADDON_MIGRATED, self.addon,
         details={'email': False}, user=self.addon.authors.get())
     res = self.post(recipients='depreliminary')
     self.assertNoFormErrors(res)
     self.assert3xx(res, reverse('zadmin.email_devs'))
     assert len(mail.outbox) == 0
コード例 #16
0
ファイル: admin.py プロジェクト: mozilla/addons-server
 def ban_action(self, request, qs):
     users = []
     UserProfile.ban_and_disable_related_content_bulk(qs)
     for obj in qs:
         ActivityLog.create(amo.LOG.ADMIN_USER_BANNED, obj)
         users.append(force_text(obj))
     kw = {'users': u', '.join(users)}
     self.message_user(
         request, ugettext('The users "%(users)s" have been banned.' % kw))
コード例 #17
0
ファイル: views.py プロジェクト: piyushmittal25/addons-server
 def enable(self, request, **kwargs):
     addon = get_object_or_404(Addon, pk=kwargs['pk'])
     ActivityLog.create(amo.LOG.CHANGE_STATUS, addon, amo.STATUS_PUBLIC)
     self.log.info('Addon "%s" status changed to: %s',
                   addon.slug, amo.STATUS_PUBLIC)
     addon.update(status=amo.STATUS_PUBLIC)
     # Call update_status() to fix the status if the add-on is not actually
     # in a state that allows it to be public.
     addon.update_status()
     return Response(status=status.HTTP_202_ACCEPTED)
コード例 #18
0
ファイル: test_models.py プロジェクト: Osmose/olympia
 def test_version_log_unlisted_addon(self):
     version = Version.objects.all()[0]
     # Get the url before the addon is changed to unlisted.
     url_path = version.get_url_path()
     self.make_addon_unlisted(version.addon)
     ActivityLog.create(amo.LOG.REJECT_VERSION, version.addon, version,
                        user=self.request.user)
     entries = ActivityLog.objects.for_version(version)
     assert len(entries) == 1
     assert url_path not in unicode(entries[0])
コード例 #19
0
ファイル: test_views.py プロジェクト: Osmose/olympia
 def test_depreliminary_addon_devs(self):
     # We just need a user for the log(), it would normally be task user.
     ActivityLog.create(
         amo.LOG.PRELIMINARY_ADDON_MIGRATED, self.addon,
         details={'email': True}, user=self.addon.authors.get())
     res = self.post(recipients='depreliminary')
     self.assertNoFormErrors(res)
     self.assert3xx(res, reverse('zadmin.email_devs'))
     assert len(mail.outbox) == 1
     assert mail.outbox[0].to == ['*****@*****.**']
     assert mail.outbox[0].from_email == settings.DEFAULT_FROM_EMAIL
コード例 #20
0
ファイル: views.py プロジェクト: piyushmittal25/addons-server
 def flags(self, request, **kwargs):
     addon = get_object_or_404(Addon, pk=kwargs['pk'])
     instance, _ = AddonReviewerFlags.objects.get_or_create(addon=addon)
     serializer = AddonReviewerFlagsSerializer(
         instance, data=request.data, partial=True)
     serializer.is_valid(raise_exception=True)
     # If pending info request was modified, log it.
     if 'pending_info_request' in serializer.initial_data:
         ActivityLog.create(amo.LOG.ADMIN_ALTER_INFO_REQUEST, addon)
     serializer.save()
     return Response(serializer.data)
コード例 #21
0
ファイル: test_models.py プロジェクト: Osmose/olympia
 def test_addon_log_unlisted_addon(self):
     addon = Addon.objects.get()
     # Get the url before the addon is changed to unlisted.
     url_path = addon.get_url_path()
     self.make_addon_unlisted(addon)
     # Delete the status change log entry from making versions unlisted.
     ActivityLog.objects.for_addons(addon).delete()
     ActivityLog.create(amo.LOG.CREATE_ADDON, (Addon, addon.id))
     entries = ActivityLog.objects.for_addons(addon)
     assert len(entries) == 1
     assert url_path not in unicode(entries[0])
コード例 #22
0
ファイル: test_views.py プロジェクト: Osmose/olympia
 def test_get_index(self):
     # Add fake log that would be shown in the index page.
     user = UserProfile.objects.get(email='*****@*****.**')
     ActivityLog.create(
         amo.LOG.GROUP_USER_ADDED, user.groups.latest('pk'), user,
         user=user)
     url = reverse('zadmin.index')
     response = self.client.get(url, follow=True)
     assert response.status_code == 200
     assert response.context['user'].username == 'admin'
     assert response.context['user'].email == '*****@*****.**'
コード例 #23
0
ファイル: test_models.py プロジェクト: Osmose/olympia
 def test_beta_signed_events_validation_ignored(self):
     addon = Addon.objects.get()
     file_ = addon.versions.first().files.first()
     # Signed beta file which passed validation.
     ActivityLog.create(amo.LOG.BETA_SIGNED, file_)
     log = ActivityLog.objects.beta_signed_events().first().to_string()
     link = pq(log)('a')
     assert len(link) == 1
     assert link[0].attrib['href'] == reverse('files.list', args=[file_.pk])
     msg = '<a href="{0}">{1}</a> (validation ignored) was signed.'.format(
         reverse('files.list', args=[file_.pk]), file_.filename)
     assert log == msg
コード例 #24
0
 def test_dont_show_request_for_information_if_none_pending(self):
     self.user = UserProfile.objects.latest('pk')
     ActivityLog.create(
         amo.LOG.REVIEWER_REPLY_VERSION, self.addon, self.version,
         user=self.user, details={'comments': 'this should not be shown'})
     ActivityLog.create(
         amo.LOG.REQUEST_INFORMATION, self.addon, self.version,
         user=self.user, details={'comments': 'this is an info request'})
     response = self.client.get(self.url)
     assert response.status_code == 200
     assert 'this should not be shown' not in response.content
     assert 'this is an info request' not in response.content
コード例 #25
0
ファイル: forms.py プロジェクト: Osmose/olympia
    def save(self, commit=True):
        ob = super(PolicyForm, self).save(commit)
        for k, field in (('has_eula', 'eula'),
                         ('has_priv', 'privacy_policy')):
            if not self.cleaned_data[k]:
                delete_translation(self.instance, field)

        if 'privacy_policy' in self.changed_data:
            ActivityLog.create(amo.LOG.CHANGE_POLICY, self.addon,
                               self.instance)

        return ob
コード例 #26
0
ファイル: forms.py プロジェクト: piyushmittal25/addons-server
 def save(self, *args, **kw):
     profile = super(AdminUserEditForm, self).save(log_for_developer=False)
     if self.cleaned_data['anonymize']:
         ActivityLog.create(amo.LOG.ADMIN_USER_ANONYMIZED, self.instance,
                            self.cleaned_data['admin_log'])
         profile.delete()  # This also logs
     else:
         ActivityLog.create(amo.LOG.ADMIN_USER_EDITED, self.instance,
                            self.cleaned_data['admin_log'],
                            details=self.changes())
         log.info('Admin edit user: %s changed fields: %s' %
                  (self.instance, self.changed_fields()))
     return profile
コード例 #27
0
ファイル: test_models.py プロジェクト: Osmose/olympia
 def test_user_log_as_argument(self):
     """
     Tests that a user that has something done to them gets into the user
     log.
     """
     user = UserProfile(username='******')
     user.save()
     ActivityLog.create(amo.LOG.ADD_USER_WITH_ROLE,
                        user, 'developer', Addon.objects.get())
     entries = ActivityLog.objects.for_user(self.request.user)
     assert len(entries) == 1
     entries = ActivityLog.objects.for_user(user)
     assert len(entries) == 1
コード例 #28
0
ファイル: test_views_themes.py プロジェクト: Osmose/olympia
    def test_dashboard_review_counts(self):
        theme = addon_factory(type=amo.ADDON_PERSONA)
        for i in range(3):
            ActivityLog.create(amo.LOG.THEME_REVIEW, theme,
                               user=UserProfile.objects.get())

        r = home(self.request)
        assert r.status_code == 200

        doc = pq(r.content)
        # Total reviews.
        assert doc('.editor-stats-table:first-child td.int').text() == '3'
        # Reviews monthly.
        assert doc('.editor-stats-table:last-child td.int').text() == '3'
コード例 #29
0
ファイル: utils.py プロジェクト: bqbn/addons-server
def log_and_notify(action, comments, note_creator, version, perm_setting=None,
                   detail_kwargs=None):
    """Record an action through ActivityLog and notify relevant users about it.
    """
    log_kwargs = {
        'user': note_creator,
        'created': datetime.now(),
    }
    if detail_kwargs is None:
        detail_kwargs = {}
    if comments:
        detail_kwargs['version'] = version.version
        detail_kwargs['comments'] = comments
    if detail_kwargs:
        log_kwargs['details'] = detail_kwargs

    note = ActivityLog.create(action, version.addon, version, **log_kwargs)
    if not note:
        return

    notify_about_activity_log(
        version.addon, version, note, perm_setting=perm_setting)

    if action == amo.LOG.DEVELOPER_REPLY_VERSION:
        # When a developer repies by email, we automatically clear the
        # corresponding info request.
        AddonReviewerFlags.objects.update_or_create(
            addon=version.addon, defaults={'pending_info_request': None}
        )

    return note
コード例 #30
0
ファイル: test_utils.py プロジェクト: tsl143/addons-server
def test_send_activity_mail():
    subject = u'This ïs ã subject'
    message = u'And... this ïs a messãge!'
    addon = addon_factory()
    latest_version = addon.find_latest_version(
        channel=amo.RELEASE_CHANNEL_LISTED)
    user = user_factory()
    recipients = [user, ]
    from_email = '*****@*****.**'
    action = ActivityLog.create(amo.LOG.DEVELOPER_REPLY_VERSION, user=user)
    send_activity_mail(
        subject, message, latest_version, recipients, from_email, action.id)

    assert len(mail.outbox) == 1
    assert mail.outbox[0].body == message
    assert mail.outbox[0].subject == subject
    uuid = latest_version.token.get(user=user).uuid.hex
    reference_header = '<{addon}/{version}@{site}>'.format(
        addon=latest_version.addon.id, version=latest_version.id,
        site=settings.INBOUND_EMAIL_DOMAIN)
    message_id = '<{addon}/{version}/{action}@{site}>'.format(
        addon=latest_version.addon.id, version=latest_version.id,
        action=action.id, site=settings.INBOUND_EMAIL_DOMAIN)

    assert mail.outbox[0].extra_headers['In-Reply-To'] == reference_header
    assert mail.outbox[0].extra_headers['References'] == reference_header
    assert mail.outbox[0].extra_headers['Message-ID'] == message_id

    reply_email = 'reviewreply+%s@%s' % (uuid, settings.INBOUND_EMAIL_DOMAIN)
    assert mail.outbox[0].reply_to == [reply_email]
コード例 #31
0
    def test_pending_activity_count(self):
        v2, _ = self._extra_version_and_file(amo.STATUS_AWAITING_REVIEW)
        # Add some activity log messages
        ActivityLog.create(amo.LOG.REQUEST_INFORMATION,
                           v2.addon,
                           v2,
                           user=self.user)
        ActivityLog.create(amo.LOG.REQUEST_INFORMATION,
                           v2.addon,
                           v2,
                           user=self.user)

        response = self.client.get(self.url)
        assert response.status_code == 200
        doc = pq(response.content)

        # Two versions, but three review-history-show because one reply link.
        assert doc('.review-history-show').length == 3
        # Two versions, but only one counter, for the latest/deleted version
        pending_activity_count = doc('.review-history-pending-count')
        assert pending_activity_count.length == 1
        # There are two activity logs pending
        assert pending_activity_count.text() == '2'
コード例 #32
0
    def approve_latest_version(self):
        """Set an unlisted addon version files to public."""
        assert self.version.channel == amo.RELEASE_CHANNEL_UNLISTED

        # Sign addon.
        self.sign_files()
        for file_ in self.files:
            ActivityLog.create(amo.LOG.UNLISTED_SIGNED, file_, user=self.user)

        self.set_files(amo.STATUS_APPROVED, self.files)

        template = u'unlisted_to_reviewed_auto'
        subject = u'Mozilla Add-ons: %s %s signed and ready to download'
        self.log_action(amo.LOG.APPROVE_VERSION)

        if self.human_review:
            self.clear_specific_needs_human_review_flags(self.version)

        self.notify_email(template, subject, perm_setting=None)

        log.info(u'Making %s files %s public' %
                 (self.addon, ', '.join([f.filename for f in self.files])))
        log.info(u'Sending email for %s' % (self.addon))
コード例 #33
0
    def test_version_log_transformer(self):
        addon = Addon.objects.get()
        version = addon.current_version
        ActivityLog.create(
            amo.LOG.REJECT_VERSION, addon, version, user=self.request.user
        )

        version_two = version_factory(
            addon=addon, license=version.license, version='1.2.3'
        )

        ActivityLog.create(
            amo.LOG.REJECT_VERSION, addon, version_two, user=self.request.user
        )

        versions = (
            Version.objects.filter(addon=addon)
            .order_by('-created')
            .transform(Version.transformer_activity)
        )

        assert len(versions[0].all_activity) == 1
        assert len(versions[1].all_activity) == 1
コード例 #34
0
    def log_action(self, action, version=None, files=None):
        details = {
            'comments': self.data['comments'],
            'reviewtype': self.review_type
        }
        if files is None and self.files:
            files = self.files
        if files is not None:
            details['files'] = [f.id for f in files]
        if version is None and self.version:
            version = self.version
        if version is not None:
            details['version'] = version.version
            args = (self.addon, version)
        else:
            args = (self.addon, )

        kwargs = {
            'user': self.user,
            'created': datetime.datetime.now(),
            'details': details
        }
        ActivityLog.create(action, *args, **kwargs)
コード例 #35
0
ファイル: test_models.py プロジェクト: copyit/addons-server
 def test_review_action_reason_log(self):
     addon = Addon.objects.get()
     assert ReviewActionReasonLog.objects.count() == 0
     # Creating an activity log without any `reason` arguments doesn't
     # create a ReviewActionReasonLog.
     action = amo.LOG.REJECT_VERSION
     ActivityLog.create(
         action,
         addon,
         addon.current_version,
         user=self.request.user,
     )
     assert ReviewActionReasonLog.objects.count() == 0
     # Creating an activity log with one or more`reason` arguments does
     # create ReviewActionReasonLogs.
     reason_1 = ReviewActionReason.objects.create(
         name='a reason',
         is_active=True,
     )
     reason_2 = ReviewActionReason.objects.create(
         name='reason 2',
         is_active=True,
     )
     ActivityLog.create(
         action,
         addon,
         addon.current_version,
         reason_1,
         reason_2,
         user=self.request.user,
     )
     assert ReviewActionReasonLog.objects.count() == 2
     reason_ids_from_logs = [
         log.reason_id for log in ReviewActionReasonLog.objects.all()
     ]
     assert sorted(reason_ids_from_logs) == sorted(
         [reason_1.id, reason_2.id])
コード例 #36
0
    def test_email_is_sent_to_relevant_people_for_source_code_upload(self):
        # Have a reviewer review a version.
        reviewer = user_factory()
        self.grant_permission(reviewer, 'Addons:Review')
        ActivityLog.create(amo.LOG.REJECT_VERSION_DELAYED,
                           self.addon,
                           self.version,
                           user=reviewer)

        # Add an extra developer to the add-on
        extra_author = user_factory()
        self.addon.authors.add(extra_author)

        # Add someone in group meant to receive a copy of all activity emails.
        group, _ = Group.objects.get_or_create(name=ACTIVITY_MAIL_GROUP)
        staff_user = user_factory()
        staff_user.groups.add(group)

        # Have the developer upload source file for the version reviewed.
        self.test_should_accept_zip_source_file()

        # Check that an email has been sent to relevant people.
        assert len(mail.outbox) == 3
        for message in mail.outbox:
            assert message.subject == (
                'Mozilla Add-ons: Delicious Bookmarks 2.1.072')
            assert 'Source code uploaded' in message.body

        # Check each message was sent separately to who we are meant to notify.
        assert mail.outbox[0].to != mail.outbox[1].to != mail.outbox[2].to
        assert set(mail.outbox[0].to + mail.outbox[1].to +
                   mail.outbox[2].to) == {
                       reviewer.email,
                       extra_author.email,
                       staff_user.email,
                   }
コード例 #37
0
def test_pending_activity_log_count_for_developer(action1, action2, action3,
                                                  count):
    user = user_factory()
    addon = addon_factory()
    version = addon.current_version
    ActivityLog.create(action1, addon, version,
                       user=user).update(created=days_ago(2))
    ActivityLog.create(action2, addon, version,
                       user=user).update(created=days_ago(1))
    ActivityLog.create(action3, addon, version,
                       user=user).update(created=days_ago(0))

    assert helpers.pending_activity_log_count_for_developer(version) == count
コード例 #38
0
ファイル: test_views.py プロジェクト: copyit/addons-server
    def test_get_unique_bad_results(self):
        version_1 = version_factory(addon=addon_factory(), version='1.0')
        ScannerResult.objects.create(scanner=MAD, version=version_1)
        ActivityLog.create(amo.LOG.BLOCKLIST_BLOCK_ADDED,
                           version_1,
                           user=self.user)
        ActivityLog.create(amo.LOG.BLOCKLIST_BLOCK_EDITED,
                           version_1,
                           user=self.user)
        version_2 = version_factory(addon=addon_factory(), version='2.0')
        ScannerResult.objects.create(scanner=MAD, version=version_2)
        ActivityLog.create(amo.LOG.BLOCKLIST_BLOCK_ADDED,
                           version_2,
                           user=self.user)
        ActivityLog.create(amo.LOG.BLOCKLIST_BLOCK_EDITED,
                           version_2,
                           user=self.user)

        response = self.client.get(f'{self.url}?label=bad')
        results = self.assert_json_results(response, expected_results=2)
        assert results[0]['id'] != results[1]['id']
コード例 #39
0
    def test_activity(self):
        addon = addon_factory()
        core.set_user(self.user)
        ActivityLog.create(amo.LOG.CREATE_ADDON, addon)
        ActivityLog.create(amo.LOG.EDIT_PROPERTIES, addon)

        # Create another activity attached to a different user.
        someone_else = user_factory()
        core.set_user(someone_else)
        ActivityLog.create(amo.LOG.EDIT_PROPERTIES, addon)
        url, text = self._call_related_content_method('activity')
        expected_url = (reverse('admin:activity_activitylog_changelist') +
                        '?user=%d' % self.user.pk)
        assert url == expected_url
        assert text == '2'
コード例 #40
0
    def log_action(self, action, version=None, files=None, timestamp=None):
        details = {
            'comments': self.data.get('comments', ''),
            'reviewtype': self.review_type.split('_')[1]
        }
        if files is None and self.files:
            files = self.files
        if files is not None:
            details['files'] = [f.id for f in files]
        if version is None and self.version:
            version = self.version
        if version is not None:
            details['version'] = version.version
            args = (self.addon, version)
        else:
            args = (self.addon, )
        if timestamp is None:
            timestamp = datetime.now()

        kwargs = {'user': self.user, 'created': timestamp, 'details': details}
        self.log_entry = ActivityLog.create(action, *args, **kwargs)
コード例 #41
0
    def test_get_by_label_and_scanner(self):
        self.create_switch('enable-scanner-results-api', active=True)
        # result labelled as "bad" because its state is TRUE_POSITIVE
        bad_version = version_factory(addon=addon_factory())
        ScannerResult.objects.create(
            scanner=YARA, version=bad_version, state=TRUE_POSITIVE
        )
        # result labelled as "good" because it has been approved
        good_version = version_factory(addon=addon_factory())
        ScannerResult.objects.create(scanner=WAT, version=good_version)
        VersionLog.objects.create(
            activity_log=ActivityLog.create(
                action=amo.LOG.APPROVE_VERSION,
                version=good_version,
                user=self.user,
            ),
            version=good_version,
        )

        response = self.client.get(self.url)
        self.assert_json_results(response, expected_results=2)

        response = self.client.get(
            '{}'.format('{}?scanner=yara&label=good'.format(self.url))
        )
        self.assert_json_results(response, expected_results=0)
        response = self.client.get(
            '{}'.format('{}?scanner=yara&label=bad'.format(self.url))
        )
        self.assert_json_results(response, expected_results=1)

        response = self.client.get(
            '{}'.format('{}?scanner=wat&label=bad'.format(self.url))
        )
        self.assert_json_results(response, expected_results=0)
        response = self.client.get(
            '{}'.format('{}?scanner=wat&label=good'.format(self.url))
        )
        self.assert_json_results(response, expected_results=1)
コード例 #42
0
def log_and_notify(
    action, comments, note_creator, version, perm_setting=None, detail_kwargs=None
):
    """Record an action through ActivityLog and notify relevant users about it."""
    log_kwargs = {
        'user': note_creator,
        'created': datetime.now(),
    }
    if detail_kwargs is None:
        detail_kwargs = {}
    if comments:
        detail_kwargs['version'] = version.version
        detail_kwargs['comments'] = comments
    if detail_kwargs:
        log_kwargs['details'] = detail_kwargs

    note = ActivityLog.create(action, version.addon, version, **log_kwargs)
    if not note:
        return

    notify_about_activity_log(version.addon, version, note, perm_setting=perm_setting)
    return note
コード例 #43
0
    def test_get_results_with_good_blocked_versions(self):
        self.create_switch('enable-scanner-results-api', active=True)
        # Result labelled as "good" because auto-approve has been confirmed.
        version_1 = version_factory(addon=addon_factory())
        result_1 = ScannerResult.objects.create(scanner=CUSTOMS,
                                                version=version_1)
        VersionLog.objects.create(
            activity_log=ActivityLog.create(
                action=amo.LOG.CONFIRM_AUTO_APPROVED,
                version=version_1,
                user=self.user,
            ),
            version=version_1,
        )
        # Oh noes! The version has been blocked.
        block_1 = Block.objects.create(guid=version_1.addon.guid,
                                       updated_by=self.user)
        block_activity_log_save(block_1, change=False)

        response = self.client.get(self.url)
        results = self.assert_json_results(response, expected_results=1)
        assert results[0]['id'] == result_1.id
        assert results[0]['label'] == LABEL_BAD
コード例 #44
0
def test_send_activity_mail():
    subject = 'This ïs ã subject'
    message = 'And... this ïs a messãge!'
    addon = addon_factory()
    latest_version = addon.find_latest_version(
        channel=amo.RELEASE_CHANNEL_LISTED)
    user = user_factory()
    recipients = [
        user,
    ]
    from_email = '*****@*****.**'
    action = ActivityLog.create(amo.LOG.DEVELOPER_REPLY_VERSION, user=user)
    send_activity_mail(subject, message, latest_version, recipients,
                       from_email, action.id)

    assert len(mail.outbox) == 1
    assert mail.outbox[0].body == message
    assert mail.outbox[0].subject == subject
    uuid = latest_version.token.get(user=user).uuid.hex
    reference_header = '<{addon}/{version}@{site}>'.format(
        addon=latest_version.addon.id,
        version=latest_version.id,
        site=settings.INBOUND_EMAIL_DOMAIN,
    )
    message_id = '<{addon}/{version}/{action}@{site}>'.format(
        addon=latest_version.addon.id,
        version=latest_version.id,
        action=action.id,
        site=settings.INBOUND_EMAIL_DOMAIN,
    )

    assert mail.outbox[0].extra_headers['In-Reply-To'] == reference_header
    assert mail.outbox[0].extra_headers['References'] == reference_header
    assert mail.outbox[0].extra_headers['Message-ID'] == message_id

    reply_email = f'reviewreply+{uuid}@{settings.INBOUND_EMAIL_DOMAIN}'
    assert mail.outbox[0].reply_to == [reply_email]
コード例 #45
0
ファイル: test_models.py プロジェクト: st333v/addons-server
    def test_change_status(self):
        addon = Addon.objects.get()
        log = ActivityLog.create(amo.LOG.CHANGE_STATUS, addon, amo.STATUS_APPROVED)
        expected = (
            '<a href="/en-US/firefox/addon/a3615/">'
            'Delicious Bookmarks</a> status changed to Approved.'
        )
        assert str(log) == expected

        log.arguments = [amo.STATUS_DISABLED, addon]
        expected = (
            '<a href="/en-US/firefox/addon/a3615/">'
            'Delicious Bookmarks</a> status changed to '
            'Disabled by Mozilla.'
        )
        assert str(log) == expected

        log.arguments = [addon, amo.STATUS_NULL]
        expected = (
            '<a href="/en-US/firefox/addon/a3615/">'
            'Delicious Bookmarks</a> status changed to Incomplete.'
        )
        assert str(log) == expected

        log.arguments = [addon, 666]
        expected = (
            '<a href="/en-US/firefox/addon/a3615/">'
            'Delicious Bookmarks</a> status changed to 666.'
        )
        assert str(log) == expected

        log.arguments = [addon, 'Some String']
        expected = (
            '<a href="/en-US/firefox/addon/a3615/">'
            'Delicious Bookmarks</a> status changed to Some String.'
        )
        assert str(log) == expected
コード例 #46
0
 def setUp(self):
     self.user1 = user_factory()
     self.user2 = user_factory()
     self.user3 = user_factory()
     self.addon1 = addon_factory()
     self.addon2 = addon_factory()
     # First user approved content of addon1.
     ActivityLog.create(
         amo.LOG.APPROVE_CONTENT, self.addon1,
         self.addon1.current_version, user=self.user1)
     # Second user confirmed auto-approved of addon2.
     ActivityLog.create(
         amo.LOG.CONFIRM_AUTO_APPROVED, self.addon2,
         self.addon2.current_version, user=self.user2)
     # Third user approved content of addon2.
     ActivityLog.create(
         amo.LOG.APPROVE_CONTENT, self.addon2,
         self.addon2.current_version, user=self.user3,)
コード例 #47
0
ファイル: utils.py プロジェクト: soniasingla/addons-server
def log_and_notify(action,
                   comments,
                   note_creator,
                   version,
                   perm_setting=None,
                   detail_kwargs=None):
    """Record an action through ActivityLog and notify relevant users about it.
    """
    log_kwargs = {
        'user': note_creator,
        'created': datetime.now(),
    }
    if detail_kwargs is None:
        detail_kwargs = {}
    if comments:
        detail_kwargs['version'] = version.version
        detail_kwargs['comments'] = comments
    if detail_kwargs:
        log_kwargs['details'] = detail_kwargs

    note = ActivityLog.create(action, version.addon, version, **log_kwargs)
    if not note:
        return

    notify_about_activity_log(version.addon,
                              version,
                              note,
                              perm_setting=perm_setting)

    if action == amo.LOG.DEVELOPER_REPLY_VERSION:
        # When a developer repies by email, we automatically clear the
        # corresponding info request.
        AddonReviewerFlags.objects.update_or_create(
            addon=version.addon, defaults={'pending_info_request': None})

    return note
コード例 #48
0
    def test_no_developer_actions(self):
        addon = self.new_addon(version='1.0')
        ActivityLog.create(amo.LOG.ADD_VERSION, addon.latest_unlisted_version,
                           addon, user=UserProfile.objects.get(pk=999))
        row = self.Queue.objects.all()[0]
        assert row.review_version_num is None

        ver2 = version_factory(version='2.0', addon=addon,
                               channel=self.channel)
        ActivityLog.create(amo.LOG.APPROVE_VERSION, ver2, addon,
                           user=UserProfile.objects.get(pk=999))
        row = self.Queue.objects.all()[0]
        assert row.review_version_num == '2.0'

        ver3 = version_factory(version='3.0', addon=addon,
                               channel=self.channel)
        ActivityLog.create(amo.LOG.EDIT_VERSION, ver3, addon,
                           user=UserProfile.objects.get(pk=999))
        row = self.Queue.objects.all()[0]
        # v2.0 is still the last reviewed version.
        assert row.review_version_num == '2.0'
コード例 #49
0
 def test_user_log(self):
     request = self.request
     ActivityLog.create(amo.LOG.CUSTOM_TEXT, 'hi there')
     entries = ActivityLog.objects.for_user(request.user)
     assert len(entries) == 1
コード例 #50
0
 def test_log_not_admin(self):
     ActivityLog.create(amo.LOG.EDIT_VERSION, Addon.objects.get())
     assert len(ActivityLog.objects.admin_events()) == 0
     assert len(ActivityLog.objects.for_developer()) == 1
コード例 #51
0
 def test_log_admin(self):
     ActivityLog.create(amo.LOG.OBJECT_EDITED, Addon.objects.get())
     assert len(ActivityLog.objects.admin_events()) == 1
     assert len(ActivityLog.objects.for_developer()) == 0
コード例 #52
0
 def test_not_total(self):
     ActivityLog.create(amo.LOG.EDIT_VERSION, Addon.objects.get())
     assert len(ActivityLog.objects.total_reviews()) == 0
コード例 #53
0
 def test_review_last_month(self):
     log = ActivityLog.create(amo.LOG.APPROVE_VERSION, Addon.objects.get())
     log.update(created=self.lm)
     assert len(ActivityLog.objects.monthly_reviews()) == 0
コード例 #54
0
 def test_review_count(self):
     ActivityLog.create(amo.LOG.APPROVE_VERSION, Addon.objects.get())
     result = ActivityLog.objects.monthly_reviews()
     assert len(result) == 1
     assert result[0]['approval_count'] == 1
     assert result[0]['user'] == self.user.pk
コード例 #55
0
 def test_not_review_count(self):
     ActivityLog.create(amo.LOG.EDIT_VERSION, Addon.objects.get())
     assert len(ActivityLog.objects.monthly_reviews()) == 0
コード例 #56
0
 def add_approve_logs(self, count):
     for x in range(0, count):
         ActivityLog.create(amo.LOG.APPROVE_VERSION, Addon.objects.get())
コード例 #57
0
 def test_output(self):
     ActivityLog.create(amo.LOG.CUSTOM_TEXT, 'hi there')
     entry = ActivityLog.objects.get()
     assert unicode(entry) == 'hi there'
コード例 #58
0
 def test_no_arguments(self):
     ActivityLog.create(amo.LOG.CUSTOM_HTML)
     entry = ActivityLog.objects.get()
     assert entry.arguments == []
コード例 #59
0
 def test_addon_log(self):
     addon = Addon.objects.get()
     ActivityLog.create(amo.LOG.CREATE_ADDON, (Addon, addon.id))
     entries = ActivityLog.objects.for_addons(addon)
     assert len(entries) == 1
     assert addon.get_url_path() in unicode(entries[0])
コード例 #60
0
 def test_no_user(self):
     core.set_user(None)
     count = ActivityLog.objects.count()
     ActivityLog.create(amo.LOG.CUSTOM_TEXT, 'hi')
     assert count == ActivityLog.objects.count()