def test_user_review_history(self): addon_factory(type=amo.ADDON_PERSONA, status=self.status) reviewer = self.create_and_become_reviewer() res = self.client.get(reverse('reviewers.themes.history')) eq_(res.status_code, 200) doc = pq(res.content) eq_(doc('tbody tr').length, 0) theme = Persona.objects.all()[0] for x in range(3): amo.log(amo.LOG.THEME_REVIEW, theme.addon, user=reviewer, details={'action': rvw.ACTION_APPROVE, 'comment': '', 'reject_reason': ''}) res = self.client.get(reverse('reviewers.themes.history')) eq_(res.status_code, 200) doc = pq(res.content) eq_(doc('tbody tr').length, 3) res = self.client.get(reverse('reviewers.themes.logs')) eq_(res.status_code, 200) doc = pq(res.content) eq_(doc('tbody tr').length, 3 * 2) # Double for comment rows.
def test_mix_pending_flagged_data_id(self): """ Case where reviewer holds locks for both pending and flagged themes. Calculating theme_lock_count on themes_more should be correct. """ reviewer = self.create_and_become_reviewer() # Check out pending themes. addon_factory(type=amo.ADDON_PERSONA, status=amo.STATUS_PENDING) req = self.req_factory_factory(reviewer, 'reviewers.themes.queue_themes') _get_themes(req, req.user.get_profile(), initial=True) # Check out flagged themes. for x in range(rvw.THEME_INITIAL_LOCKS + 1): addon_factory(type=amo.ADDON_PERSONA, status=amo.STATUS_REVIEW_PENDING) req = self.req_factory_factory(reviewer, 'reviewers.themes.queue_flagged') _get_themes(req, req.user.get_profile(), initial=True, flagged=True) # Get more flagged themes. req = self.req_factory_factory(reviewer, 'reviewers.themes.more_flagged') res = themes_more(req, flagged=True) themes = pq(json.loads(res.content)['html'])('.theme') eq_(pq(themes[0]).attr('data-id'), '2')
def test_hotness_normal_binary_components(self): waffle.models.Switch.objects.create(name="d2c-at-the-disco", active=True) # Add a 3rd add-on that should get filtered out b/c of compatibility. addon_factory(hotness=50, version_kw=dict(max_app_version="7.0"), file_kw=dict(binary_components=True)) res = self.client.get(self._url(version="12.0", compat_mode="normal")) eq_(res.status_code, 200) eq_(pq(res.content)(".featured-addons").length, 2)
def test_hotness_normal_binary_components(self): # Add a 3rd add-on that should get filtered out b/c of compatibility. addon_factory(hotness=50, version_kw=dict(max_app_version='7.0'), file_kw=dict(binary_components=True)) res = self.client.get(self._url(version='12.0', compat_mode='normal')) eq_(res.status_code, 200) eq_(pq(res.content)('.featured-addons').length, 2)
def test_themes_less_than_initial(self): """ Number of themes in the pool is less than amount we want to check out. """ addon_factory(type=amo.ADDON_PERSONA, status=self.status) reviewer = self.create_and_become_reviewer() eq_(len(_get_themes(mock.Mock(), reviewer)), 1) eq_(len(_get_themes(mock.Mock(), reviewer)), 1)
def test_expiry_update(self): """Test expiry is updated when reviewer reloads his queue.""" addon_factory(type=amo.ADDON_PERSONA, status=self.status) reviewer = self.create_and_become_reviewer() _get_themes(mock.Mock(), reviewer, initial=True, flagged=self.flagged) earlier = datetime.datetime.now() - datetime.timedelta(minutes=10) ThemeLock.objects.filter(reviewer=reviewer).update(expiry=earlier) _get_themes(mock.Mock(), reviewer, initial=True, flagged=self.flagged) eq_(ThemeLock.objects.filter(reviewer=reviewer)[0].expiry > earlier, True)
def test_expiry_update(self): """Test expiry is updated when reviewer reloads his queue.""" addon_factory(type=amo.ADDON_PERSONA, status=self.status) reviewer = self.create_and_become_reviewer() _get_themes(mock.Mock(), reviewer, flagged=self.flagged) ThemeLock.objects.filter(reviewer=reviewer).update(expiry=days_ago(1)) _get_themes(mock.Mock(), reviewer, flagged=self.flagged) eq_(ThemeLock.objects.filter(reviewer=reviewer)[0].expiry > days_ago(1), True)
def test_hotness_normal_strict_opt_in(self): waffle.models.Switch.objects.create(name='d2c-at-the-disco', active=True) # Add a 3rd add-on that should get filtered out b/c of compatibility. addon_factory(hotness=50, version_kw=dict(max_app_version='7.0'), file_kw=dict(strict_compatibility=True)) res = self.client.get(self._url(version='12.0', compat_mode='normal')) eq_(res.status_code, 200) eq_(pq(res.content)('.featured-addons').length, 2)
def themes_more_helper(self): for x in range(rvw.THEME_INITIAL_LOCKS * 2): addon_factory(type=amo.ADDON_PERSONA, status=self.status) reviewer = self.create_and_become_reviewer() req = self.req_factory_factory(reviewer, "reviewers.themes.more") themes = _get_themes(req, req.user.get_profile(), initial=True, flagged=self.flagged) eq_(len(themes), 2) return req, themes
def test_top_off(self): """If reviewer has fewer than max locks, get more from pool.""" for x in range(2): addon_factory(type=amo.ADDON_PERSONA, status=self.status) reviewer = self.create_and_become_reviewer() _get_themes(mock.Mock(), reviewer, initial=True, flagged=self.flagged) ThemeLock.objects.filter(reviewer=reviewer)[0].delete() _get_themes(mock.Mock(), reviewer, initial=True, flagged=self.flagged) # Check reviewer checked out the themes. eq_(ThemeLock.objects.filter(reviewer=reviewer).count(), rvw.THEME_INITIAL_LOCKS)
def test_manager_hard_delete_addons(self): """Test manager excludes soft delete add-ons.""" RereviewQueueTheme.objects.create(theme=addon_factory(type=amo.ADDON_PERSONA).persona, header="", footer="") # Deleted add-on RQT object. addon = addon_factory(type=amo.ADDON_PERSONA) RereviewQueueTheme.objects.create(theme=addon.persona, header="", footer="") addon.delete() eq_(RereviewQueueTheme.objects.count(), 1) eq_(RereviewQueueTheme.with_deleted.count(), 1)
def test_all_results(self): for x in range(4): addon_factory(name='chr' + str(x), type=amo.ADDON_WEBAPP) self.refresh('webapp') # Test search limit. data = self.search(q='chr') eq_(len(data['results']), 2) # Test maximum search result. data = self.search(q='chr', all_results=True) eq_(len(data['results']), 3)
def test_basic_queue(self): """ Have reviewers take themes from the pool, check their queue sizes. """ for x in range(rvw.THEME_INITIAL_LOCKS + 1): addon_factory(type=amo.ADDON_PERSONA, status=self.status) themes = Persona.objects.all() expected_themes = [[themes[0], themes[1]], [themes[2]], []] for expected in expected_themes: reviewer = self.create_and_become_reviewer() eq_(_get_themes(mock.Mock(), reviewer, initial=False, flagged=self.flagged), expected) eq_(ThemeLock.objects.filter(reviewer=reviewer).count(), len(expected))
def test_more(self): """ Test number of themes checked out when asking for more asynchronously. """ for x in range(rvw.THEME_INITIAL_LOCKS + 1): addon_factory(type=amo.ADDON_PERSONA, status=self.status) themes = Persona.objects.all() expected_themes = [[themes[0], themes[1]], [themes[2]], []] reviewer = self.create_and_become_reviewer() for expected in expected_themes: actual = _get_themes(mock.Mock(), reviewer, initial=False, flagged=self.flagged) eq_(actual, expected)
def test_manager_soft_delete_addons(self): """Test manager excludes soft delete add-ons.""" # Normal RQT object. RereviewQueueTheme.objects.create( theme=addon_factory(type=amo.ADDON_PERSONA).persona, header='', footer='') # Deleted add-on RQT object. addon = addon_factory(type=amo.ADDON_PERSONA) RereviewQueueTheme.objects.create( theme=addon.persona, header='', footer='') addon.delete() eq_(RereviewQueueTheme.objects.count(), 1) eq_(RereviewQueueTheme.unfiltered.count(), 2)
def test_release_locks(self): for x in range(2): addon_factory(type=amo.ADDON_PERSONA, status=self.status) other_reviewer = self.create_and_become_reviewer() _get_themes(mock.Mock(), other_reviewer) # Check reviewer's theme lock released. reviewer = self.create_and_become_reviewer() _get_themes(mock.Mock(), reviewer) eq_(ThemeLock.objects.filter(reviewer=reviewer).count(), 1) self.client.get(reverse('reviewers.themes.release_locks')) eq_(ThemeLock.objects.filter(reviewer=reviewer).count(), 0) # Check other reviewer's theme lock intact. eq_(ThemeLock.objects.filter(reviewer=other_reviewer).count(), 1)
def generate_addon(name, category, user): # Use default icons from the filesystem given the category. icon_type = 'icon/{slug}'.format(slug=category.slug) addon = addon_factory(name=name, icon_type=icon_type) AddonUser.objects.create(addon=addon, user=user) AddonCategory.objects.create(addon=addon, category=category, feature=True) return addon
def test_update_addon_non_existing_name(self): """An add-on edit can change the name to any non-existing name.""" addon = addon_factory(name='some name') form = forms.AddonForm(dict(name=self.non_existing_name), instance=addon) form.is_valid() assert 'name' not in form.errors
def test_receipt_packaged(self): webapp = addon_factory(type=amo.ADDON_WEBAPP) webapp.get_latest_file().update(is_packaged=True) user = UserProfile.objects.get(pk=5497308) ins = self.create_install(user, webapp) receipt = self.for_user(ins, "developer") eq_(receipt["product"]["url"], settings.SITE_URL)
def test_new_more_themes(self): other = addon_factory(type=amo.ADDON_PERSONA) self.create_addon_user(other) self.persona.persona_id = 0 self.persona.save() r = self.client.get(self.url) eq_(pq(r.content)('#more-artist').length, 1)
def test_addon_dev_denied(self): # Test when the user is a developer of a different add-on. self.thread = CommunicationThread.objects.create( addon=self.addon, read_permission_developer=True) addon = addon_factory() self.profile.addonuser_set.create(addon=addon) assert not self.check_permissions()
def test_update_addon_existing_name_used_by_other_type(self): """An add-on edit can change the name to an existing name used by another add-on type.""" addon = addon_factory(name='some name', type=amo.ADDON_PERSONA) form = forms.AddonForm(dict(name=self.existing_name), instance=addon) form.is_valid() assert 'name' not in form.errors
def test_update_addon_existing_name_used_by_listed(self): """An unlisted add-on edit can change the name to an existing name used by an listed add-on.""" addon = addon_factory(name='some name', is_listed=False) form = forms.AddonForm(dict(name=self.existing_name), instance=addon) form.is_valid() assert 'name' not in form.errors
def test_addon_dev_denied(self): # Test when the user is a developer of a different add-on. self.thread = CommunicationThread.objects.create(addon=self.addon, read_permission_developer=True) addon = addon_factory() self.profile.addonuser_set.create(addon=addon) assert not self.check_permissions()
def test_receipt_packaged(self): webapp = addon_factory(type=amo.ADDON_WEBAPP, is_packaged=True, app_domain='app://foo.com') user = UserProfile.objects.get(pk=5497308) ins = self.create_install(user, webapp) receipt = self.for_user(ins, 'developer') eq_(receipt['product']['url'], 'app://foo.com')
def test_zero_alltime_dl(self): # Downloads for some other addon that shouldn't be counted. addon = addon_factory() for user in self.users: DownloadCount.objects.create(addon=addon, count=2, date=datetime.now().date()) res = self.summary() eq_(res.context["downloads"]["alltime"], 0)
def setUp(self): super(TestAddonDownloadSummary, self).setUp() self.users = [UserProfile.objects.get(username='******'), UserProfile.objects.get(username='******')] self.addon = addon_factory() self.url = reverse('lookup.app_summary', args=[self.addon.pk]) self.login(self.users[1])
def test_new_more_themes(self): other = addon_factory(type=amo.ADDON_PERSONA) self.create_addon_user(other) self.persona.persona_id = 0 self.persona.save() r = self.client.get(self.url) eq_(pq(r.content)('#more-artist .more-link').length, 0)
def test_receipt_packaged(self): app = addon_factory(type=amo.ADDON_WEBAPP, is_packaged=True, app_domain='app://foo.com') user = UserProfile.objects.get(pk=5497308) receipt = self.for_user(app, user, 'developer') eq_(receipt['product']['url'], 'app://foo.com')
def test_version_filter_normal_binary_components(self): # Ensure we filter out strict opt-in addons in normal mode. addon3 = addon_factory(version_kw=dict(max_app_version='7.0'), file_kw=dict(binary_components=True)) addons = self.addons + [addon3] addons = addon_filter(**self._defaults(addons=addons, version='11.0', compat_mode='normal')) eq_(addons, self.addons)
def test_manager_soft_delete_addons(self): """Test manager excludes soft delete add-ons.""" # Normal RQT object. RereviewQueueTheme.objects.create( theme=addon_factory(type=amo.ADDON_PERSONA).persona, header='', footer='') # Deleted add-on RQT object. addon = addon_factory(type=amo.ADDON_PERSONA) RereviewQueueTheme.objects.create(theme=addon.persona, header='', footer='') addon.delete() eq_(RereviewQueueTheme.objects.count(), 1) eq_(RereviewQueueTheme.with_deleted.count(), 2)
def test_zero_alltime_dl(self): # Downloads for some other addon that shouldn't be counted. addon = addon_factory() for user in self.users: DownloadCount.objects.create(addon=addon, count=2, date=datetime.now().date()) res = self.summary() eq_(res.context['downloads']['alltime'], 0)
def test_version_version_less_than_min(self): # Ensure we filter out addons with a higher min than our app. addon3 = addon_factory(version_kw=dict(min_app_version='12.0', max_app_version='14.0')) addons = self.addons + [addon3] addons = addon_filter(**self._defaults(addons=addons, version='11.0', compat_mode='ignore')) eq_(addons, self.addons)
def test_rejected_addon(self): """Test rejected addons are not displayed in review lists.""" # Normal RQT object. RereviewQueueTheme.objects.create( theme=addon_factory(type=amo.ADDON_PERSONA).persona, header='', footer='') # Rejected add-on RQT object. addon = addon_factory(type=amo.ADDON_PERSONA, status=amo.STATUS_REJECTED) RereviewQueueTheme.objects.create(theme=addon.persona, header='', footer='') self.login('*****@*****.**') r = self.client.get(self.queue_url) eq_(r.status_code, 200) eq_(pq(r.content)('.theme').length, 1)
def test_filter_for_many_to_many(self): # Check https://bugzilla.mozilla.org/show_bug.cgi?id=1142035. addon = addon_factory(type=amo.ADDON_PERSONA) rqt = RereviewQueueTheme.objects.create(theme=addon.persona) assert addon.persona.rereviewqueuetheme_set.get() == rqt # Delete the addon: it shouldn't be listed anymore. addon.update(status=amo.STATUS_DELETED) assert addon.persona.rereviewqueuetheme_set.all().count() == 0
def setUp(self): super(TestAddonDownloadSummary, self).setUp() self.users = [ UserProfile.objects.get(username='******'), UserProfile.objects.get(username='******') ] self.addon = addon_factory() self.url = reverse('lookup.app_summary', args=[self.addon.pk]) self.login(self.users[1])
def test_batch_award_points_task(self): user_999 = UserProfile.objects.get(username='******') addon_999 = addon_factory() amo.log(amo.LOG.THEME_REVIEW, addon_999, details={'action': rvw.ACTION_APPROVE}, user=user_999) # No points for this one. amo.log(amo.LOG.THEME_REVIEW, addon_factory(), details={'action': rvw.ACTION_MOREINFO}, user=user_999) user_2519 = UserProfile.objects.get(username='******') addon_2519 = addon_factory() amo.log(amo.LOG.THEME_REVIEW, addon_2519, details={'action': rvw.ACTION_REJECT}, user=user_2519) # Mostly copied and pasted from award_theme_points command. approve = '"action": %s' % rvw.ACTION_APPROVE reject = '"action": %s' % rvw.ACTION_REJECT log_ids = ActivityLog.objects.filter( (Q(_details__contains=approve) | Q(_details__contains=reject)), action=amo.LOG.THEME_REVIEW.id).values_list('id', flat=True) _batch_award_points(log_ids) eq_(ReviewerScore.objects.count(), 2) points = amo.REVIEWED_SCORES.get(amo.REVIEWED_PERSONA) r1 = ReviewerScore.objects.get(user=user_999) eq_(r1.score, points) eq_(r1.note, 'RETROACTIVE') eq_(r1.addon, addon_999) eq_(r1.note_key, amo.REVIEWED_PERSONA) r2 = ReviewerScore.objects.get(user=user_2519) eq_(r2.score, points) eq_(r2.note, 'RETROACTIVE') eq_(r2.addon, addon_2519) eq_(r2.note_key, amo.REVIEWED_PERSONA)
def setUp(self): super(TestXssOnThemeName, self).setUp() self.theme = addon_factory(type=amo.ADDON_PERSONA, status=amo.STATUS_PENDING, name=self.name) persona = self.theme.persona persona.persona_id = 0 persona.header = 'header' persona.footer = 'footer' persona.save()
def test_dashboard_queue_counts(self): # Pending. addon_factory(type=amo.ADDON_PERSONA, status=amo.STATUS_PENDING) for i in range(2): # Flagged. addon_factory(type=amo.ADDON_PERSONA, status=amo.STATUS_REVIEW_PENDING) # Rereview. rereview = addon_factory(type=amo.ADDON_PERSONA, status=amo.STATUS_PUBLIC) RereviewQueueTheme.objects.create(theme=rereview.persona) r = home(self.request) eq_(r.status_code, 200) doc = pq(r.content) titles = doc('#editors-stats-charts .editor-stats-title a') eq_(titles[0].text.strip()[0], '1') # Pending count. eq_(titles[1].text.strip()[0], '2') # Flagged count. eq_(titles[2].text.strip()[0], '1') # Rereview count.
def test_locale_preferencing(self): # Add-ons matching the current locale get prioritized. addon3 = addon_factory() addon3.description = {'de': 'Unst Unst'} addon3.save() addons = self.addons + [addon3] translation.activate('de') addons = addon_filter(**self._defaults(addons=addons)) eq_(addons, [addon3] + self.addons) translation.deactivate()
def theme_factory(self, status=None): status = status or self.status addon = addon_factory(type=amo.ADDON_PERSONA, status=status) if self.rereview: RereviewQueueTheme.objects.create(theme=addon.persona, header='pending_header', footer='pending_footer') persona = addon.persona persona.header = 'header' persona.footer = 'footer' persona.save() return addon
def test_soft_deleted_addon(self): """ Test soft-deleted add-ons don't cause trouble like they did to me for the last 6 months! #liberation """ # Normal RQT object. RereviewQueueTheme.objects.create( theme=addon_factory(type=amo.ADDON_PERSONA).persona, header='', footer='') # Deleted add-on RQT object. addon = addon_factory(type=amo.ADDON_PERSONA) RereviewQueueTheme.objects.create(theme=addon.persona, header='', footer='') addon.delete() self.login('*****@*****.**') r = self.client.get(self.queue_url) eq_(r.status_code, 200) doc = pq(r.content) eq_(doc('.theme').length, 1) eq_(RereviewQueueTheme.with_deleted.count(), 2)
def test_version_filter_normal_compat_override(self): # Ensure we filter out strict opt-in addons in normal mode. addon3 = addon_factory() addons = self.addons + [addon3] # Add override for this add-on. compat = CompatOverride.objects.create(guid='three', addon=addon3) CompatOverrideRange.objects.create( compat=compat, app=Application.objects.get(pk=1), min_version=addon3.current_version.version, max_version='*') addons = addon_filter(**self._defaults(addons=addons, version='11.0', compat_mode='normal')) eq_(addons, self.addons)
def test_dashboard_review_counts(self): theme = addon_factory(type=amo.ADDON_PERSONA) for i in range(3): amo.log(amo.LOG.THEME_REVIEW, theme, user=UserProfile.objects.get()) r = home(self.request) eq_(r.status_code, 200) doc = pq(r.content) # Total reviews. eq_(doc('.editor-stats-table:first-child td.int').text(), '3') # Reviews monthly. eq_(doc('.editor-stats-table:last-child td.int').text(), '3')
def test_hotness_normal_compat_override(self): # Add a 3rd add-on that should get filtered out b/c of compatibility. addon3 = addon_factory(hotness=50, version_kw=dict(max_app_version='7.0')) # Add override for this add-on. compat = CompatOverride.objects.create(guid='three', addon=addon3) CompatOverrideRange.objects.create( compat=compat, app=Application.objects.get(pk=1), min_version=addon3.current_version.version, max_version='*') res = self.client.get(self._url(version='12.0', compat_mode='normal')) eq_(res.status_code, 200) eq_(pq(res.content)('.featured-addons').length, 2)
def setUp(self): self.uuid = 'some:uuid' self.transaction_id = 'some:tr' self.seller_uuid = 456 self.related_tx_uuid = 789 self.user = UserProfile.objects.get(pk=999) self.app = addon_factory(type=amo.ADDON_WEBAPP) self.contrib = Contribution.objects.create( addon=self.app, uuid=self.uuid, user=self.user, transaction_id=self.transaction_id) self.url = reverse('lookup.transaction_summary', args=[self.uuid]) self.client.login(username='******', password='******')
def test_search_plugin(self, parse_addon): """Test that search plugins are handled correctly.""" parse_addon.return_value = {'guid': None, 'version': '20140103'} addon = addon_factory(type=amo.ADDON_SEARCH, version_kw={'version': '20140101'}) assert addon.guid is None self.check_upload(None) self.validate_upload.reset_mock() self.save_file.reset_mock() version = version_factory(addon=addon, version='20140102') self.check_file(version.files.get(), None)
def test_other_themes(self): """Ensure listed themes by the same author show up.""" addon_factory(type=amo.ADDON_PERSONA, status=amo.STATUS_NULL) addon_factory(type=amo.ADDON_PERSONA, status=amo.STATUS_LITE) addon_factory(type=amo.ADDON_PERSONA, disabled_by_user=True) other = addon_factory(type=amo.ADDON_PERSONA) self.create_addon_user(other) eq_(other.status, amo.STATUS_PUBLIC) eq_(other.disabled_by_user, False) r = self.client.get(self.url) eq_(list(r.context['author_themes']), [other]) a = pq(r.content)('#more-artist .more a') eq_(a.length, 1) eq_(a.attr('href'), other.get_url_path())
def test_award_theme_points_command(self): # A review from before we started awarding points (award). user_999 = UserProfile.objects.get(username='******') amo.log(amo.LOG.THEME_REVIEW, addon_factory(), details={'action': rvw.ACTION_APPROVE}, user=user_999) al = ActivityLog.objects.get() al.created = datetime.date(2013, 4, 30) al.save() call_command('award_theme_points') eq_(ReviewerScore.objects.count(), 1) eq_(ReviewerScore.objects.get().note_key, amo.REVIEWED_PERSONA) eq_(ReviewerScore.objects.get().note, 'RETROACTIVE') # A review from after we started awarding points (don't award). al.created = datetime.date(2013, 8, 30) al.save() call_command('award_theme_points') eq_(ReviewerScore.objects.count(), 1)
def test_repr_when_not_extension(self): addon = addon_factory(type=amo.ADDON_THEME, version_kw=self.version_kw) version = addon.current_version eq_(version.apps.all()[0].__unicode__(), 'Firefox 5.0 - 6.*')
def test_repr_when_binary(self): addon = addon_factory(version_kw=self.version_kw, file_kw=dict(binary_components=True)) version = addon.current_version eq_(version.apps.all()[0].__unicode__(), 'Firefox 5.0 - 6.*')
def test_repr_when_strict(self): addon = addon_factory(version_kw=self.version_kw, file_kw=dict(strict_compatibility=True)) version = addon.current_version eq_(version.apps.all()[0].__unicode__(), 'Firefox 5.0 - 6.*')