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])
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.
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
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
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
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)
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
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
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})
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
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
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)
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])
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
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
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))
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)
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])
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
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)
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])
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 == '*****@*****.**'
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
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
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
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
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
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'
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
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]
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'
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))
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
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)
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])
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, }
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
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']
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'
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)
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)
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
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
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]
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
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,)
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
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'
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
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
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
def test_not_total(self): ActivityLog.create(amo.LOG.EDIT_VERSION, Addon.objects.get()) assert len(ActivityLog.objects.total_reviews()) == 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
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
def test_not_review_count(self): ActivityLog.create(amo.LOG.EDIT_VERSION, Addon.objects.get()) assert len(ActivityLog.objects.monthly_reviews()) == 0
def add_approve_logs(self, count): for x in range(0, count): ActivityLog.create(amo.LOG.APPROVE_VERSION, Addon.objects.get())
def test_output(self): ActivityLog.create(amo.LOG.CUSTOM_TEXT, 'hi there') entry = ActivityLog.objects.get() assert unicode(entry) == 'hi there'
def test_no_arguments(self): ActivityLog.create(amo.LOG.CUSTOM_HTML) entry = ActivityLog.objects.get() assert entry.arguments == []
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])
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()