def setUp(self): super(TestModelBase, self).setUp() self.saved_cb = amo.models._on_change_callbacks.copy() amo.models._on_change_callbacks.clear() self.cb = Mock() self.cb.__name__ = 'testing_mock_callback' Addon.on_change(self.cb)
def test_filter_or(self): qs = Addon.search().filter(type=1).filter(or_=dict(status=1, app=2)) filters = qs._build_query()['query']['filtered']['filter'] # Filters: # {'and': [ # {'term': {'type': 1}}, # {'or': [{'term': {'status': 1}}, {'term': {'app': 2}}]}, # ]} eq_(filters.keys(), ['and']) ok_({'term': {'type': 1}} in filters['and']) or_clause = sorted(filters['and'])[0] eq_(or_clause.keys(), ['or']) ok_({'term': {'status': 1}} in or_clause['or']) ok_({'term': {'app': 2}} in or_clause['or']) qs = Addon.search().filter(type=1, or_=dict(status=1, app=2)) filters = qs._build_query()['query']['filtered']['filter'] # Filters: # {'and': [ # {'term': {'type': 1}}, # {'or': [{'term': {'status': 1}}, {'term': {'app': 2}}]}, # ]} eq_(filters.keys(), ['and']) ok_({'term': {'type': 1}} in filters['and']) or_clause = sorted(filters['and'])[0] eq_(or_clause.keys(), ['or']) ok_({'term': {'status': 1}} in or_clause['or']) ok_({'term': {'app': 2}} in or_clause['or'])
def test_multiple_ignored(self): cb = Mock() cb.__name__ = 'something' old = len(amo.models._on_change_callbacks[Addon]) Addon.on_change(cb) eq_(len(amo.models._on_change_callbacks[Addon]), old + 1) Addon.on_change(cb) eq_(len(amo.models._on_change_callbacks[Addon]), old + 1)
def test_is_unreviewed(self): """Test if add-on is unreviewed or not""" # public add-on a = Addon.objects.get(pk=3615) assert not a.is_unreviewed(), 'public add-on: is_unreviewed=False' # unreviewed add-on a = Addon(status=amo.STATUS_UNREVIEWED) assert a.is_unreviewed(), 'sandboxed add-on: is_unreviewed=True'
def test_extra_query(self): qs = Addon.search().extra(query={'type': 1}) eq_(qs._build_query()['query']['function_score']['query'], {'term': {'type': 1}}) qs = Addon.search().filter(status=1).extra(query={'type': 1}) filtered = qs._build_query()['query']['filtered'] eq_(filtered['query']['function_score']['query'], {'term': {'type': 1}}) eq_(filtered['filter'], [{'term': {'status': 1}}])
def test_extra_order_by(self): qs = Addon.search().extra(order_by=['-rating']) eq_(qs._build_query(), {'fields': ['id'], 'sort': [{'rating': 'desc'}]}) qs = Addon.search().order_by('-id').extra(order_by=['-rating']) eq_(qs._build_query(), {'fields': ['id'], 'sort': [{'id': 'desc'}, {'rating': 'desc'}]})
def test_extra_filter(self): qs = Addon.search().extra(filter={"category__in": [1, 2]}) eq_(qs._build_query(), {"fields": ["id"], "filter": {"in": {"category": [1, 2]}}}) qs = Addon.search().filter(type=1).extra(filter={"category__in": [1, 2]}) eq_( qs._build_query(), {"fields": ["id"], "filter": {"and": [{"term": {"type": 1}}, {"in": {"category": [1, 2]}}]}}, )
def test_extra_filter(self): qs = Addon.search().extra(filter={'category__in': [1, 2]}) eq_(qs._build_query()['query']['filtered']['filter'], [{'in': {'category': [1, 2]}}]) qs = (Addon.search().filter(type=1) .extra(filter={'category__in': [1, 2]})) eq_(qs._build_query()['query']['filtered']['filter'], {'and': [{'term': {'type': 1}}, {'in': {'category': [1, 2]}}, ]})
def test_extra_query(self): qs = Addon.search().extra(query={'type': 1}) eq_(qs._build_query(), {'fields': ['id'], 'query': {'term': {'type': 1}}}) qs = Addon.search().filter(status=1).extra(query={'type': 1}) eq_(qs._build_query(), {'fields': ['id'], 'query': {'term': {'type': 1}}, 'filter': {'term': {'status': 1}}})
def test_show_beta_with_beta_version(self, beta_mock): beta_mock.return_value = object() # Fake current_beta_version to return something truthy. a = Addon(status=amo.STATUS_PUBLIC) assert a.show_beta # We have a beta version but status has to be public. a.status = amo.STATUS_UNREVIEWED assert not a.show_beta
def test_is_unreviewed(self): """Test if add-on is experimental or not""" # public add-on a = Addon.objects.get(pk=3615) assert not a.is_unreviewed(), 'public add-on: is_unreviewed=False' # experimental add-on a = Addon(status=amo.STATUS_SANDBOX) assert a.is_unreviewed(), 'sandboxed add-on: is_unreviewed=True'
def test_extra_filter_or(self): qs = Addon.search().extra(filter={'or_': {'status': 1, 'app': 2}}) eq_(qs._build_query()['query']['filtered']['filter'], [{'or': [{'term': {'status': 1}}, {'term': {'app': 2}}]}]) qs = (Addon.search().filter(type=1) .extra(filter={'or_': {'status': 1, 'app': 2}})) eq_(qs._build_query()['query']['filtered']['filter'], {'and': [{'term': {'type': 1}}, {'or': [{'term': {'status': 1}}, {'term': {'app': 2}}]}]})
def test_support_addon(self): a = Addon(id=12) eq_(support_addon(a), "") # TODO(jbalogh): check the url when using reverse a.wants_contributions = a.paypal_id = True eq_(PyQuery(support_addon(a))("a").text(), "Support this add-on") a.suggested_amount = "12" doc = PyQuery(support_addon(a)) eq_(doc(".contribute").text(), "Support this add-on: Contribute $12.00")
def test_default_locale(self): # Make sure default_locale follows the active translation. addon = Addon.from_upload(self.get_upload('search.xml'), [self.platform]) eq_(addon.default_locale, 'en-US') translation.activate('es-ES') addon = Addon.from_upload(self.get_upload('search.xml'), [self.platform]) eq_(addon.default_locale, 'es-ES') translation.deactivate()
def create_file(self, **kwargs): addon = Addon() addon.save() ver = Version(version='0.1') ver.addon = addon ver.save() f = File(**kwargs) f.version = ver f.save() return f
def test_support_addon(self): a = Addon(id=12, type=1) eq_(support_addon(a), '') a.wants_contributions = a.paypal_id = True a.status = amo.STATUS_PUBLIC eq_(PyQuery(support_addon(a))('a').text(), 'Support this add-on') a.suggested_amount = '12' doc = PyQuery(support_addon(a)) eq_(doc('.contribute').text(), 'Support this add-on: Contribute $12.00')
def test_support_addon(self): a = Addon(id=12) eq_(support_addon(a), '') # TODO(jbalogh): check the url when using reverse a.wants_contributions = a.paypal_id = True eq_(PyQuery(support_addon(a))('a').text(), 'Support this add-on') a.suggested_amount = '12' doc = PyQuery(support_addon(a)) eq_(doc('.contribute').text(), 'Support this add-on: Contribute $12.00')
def test_extra_filter_or(self): qs = Addon.search().extra(filter={"or_": {"status": 1, "app": 2}}) eq_(qs._build_query(), {"fields": ["id"], "filter": {"or": [{"term": {"status": 1}}, {"term": {"app": 2}}]}}) qs = Addon.search().filter(type=1).extra(filter={"or_": {"status": 1, "app": 2}}) eq_( qs._build_query(), { "fields": ["id"], "filter": {"and": [{"term": {"type": 1}}, {"or": [{"term": {"status": 1}}, {"term": {"app": 2}}]}]}, }, )
def test_extra_filter(self): qs = Addon.search().extra(filter={'category__in': [1, 2]}) eq_(qs._build_query(), {'fields': ['id'], 'filter': {'in': {'category': [1, 2]}}}) qs = (Addon.search().filter(type=1) .extra(filter={'category__in': [1, 2]})) eq_(qs._build_query(), {'fields': ['id'], 'filter': {'and': [ {'term': {'type': 1}}, {'in': {'category': [1, 2]}}, ]}})
def test_extra_filter(self): qs = Addon.search().extra(filter={'category__in': [1, 2]}) eq_(qs._build_query()['query']['filtered']['filter'], [{'in': {'category': [1, 2]}}]) qs = (Addon.search().filter(type=1) .extra(filter={'category__in': [1, 2]})) filters = qs._build_query()['query']['filtered']['filter'] # Filters: # {'and': [{'term': {'type': 1}}, {'in': {'category': [1, 2]}}, ]} eq_(filters.keys(), ['and']) ok_({'term': {'type': 1}} in filters['and']) ok_({'in': {'category': [1, 2]}} in filters['and'])
def test_filter_or(self): qs = Addon.search().filter(type=1).filter(or_=dict(status=1, app=2)) eq_(qs._build_query()['query']['filtered']['filter'], {'and': [ {'term': {'type': 1}}, {'or': [{'term': {'status': 1}}, {'term': {'app': 2}}]}, ]}) qs = Addon.search().filter(type=1, or_=dict(status=1, app=2)) eq_(qs._build_query()['query']['filtered']['filter'], {'and': [ {'term': {'type': 1}}, {'or': [{'term': {'status': 1}}, {'term': {'app': 2}}]}, ]})
def test_extra_filter_or(self): qs = Addon.search().extra(filter={'or_': {'status': 1, 'app': 2}}) eq_(qs._build_query(), {'fields': ['id'], 'filter': {'or': [ {'term': {'status': 1}}, {'term': {'app': 2}}]}}) qs = (Addon.search().filter(type=1) .extra(filter={'or_': {'status': 1, 'app': 2}})) eq_(qs._build_query(), {'fields': ['id'], 'filter': {'and': [ {'term': {'type': 1}}, {'or': [{'term': {'status': 1}}, {'term': {'app': 2}}]}, ]}})
def test_query_or(self): qs = Addon.search().query(or_=dict(type=1, status__gte=2)) eq_(qs._build_query(), {'fields': ['id'], 'query': {'bool': {'should': [ {'term': {'type': 1}}, {'range': {'status': {'gte': 2}}}, ]}}})
def test_facet_range(self): facet = {'range': {'status': [{'lte': 3}, {'gte': 5}]}} # Pass a copy so edits aren't propagated back here. qs = Addon.search().filter(app=1).facet(by_status=dict(facet)) eq_(qs._build_query()['query']['filtered']['filter'], [{'term': {'app': 1}}]) eq_(qs._build_query()['facets'], {'by_status': facet})
def package(request): form = forms.NewWebappForm(request.POST or None, is_packaged=True) if request.method == 'POST' and form.is_valid(): addon = Addon.from_upload( form.cleaned_data['upload'], [Platform.objects.get(id=amo.PLATFORM_ALL.id)], is_packaged=True) if addon.has_icon_in_manifest(): # Fetch the icon, do polling. addon.update(icon_type='image/png') tasks.fetch_icon.delay(addon) else: # In this case there is no need to do any polling. addon.update(icon_type='') AddonUser(addon=addon, user=request.amo_user).save() AppSubmissionChecklist.objects.create(addon=addon, terms=True, manifest=True) return redirect('submit.app.details', addon.app_slug) return jingo.render(request, 'submit/upload.html', { 'form': form, 'step': 'manifest', })
def personas(request, category=None, template=None): categories, filter, base, category = personas_listing(request, category) # Pass the count from base instead of letting it come from # filter.qs.count() since that would join against personas. count = category.count if category else base.count() if ('sort' not in request.GET and ((request.MOBILE and not category) or (not request.MOBILE and count > 4))): template += 'category_landing.html' else: template += 'grid.html' addons = amo.utils.paginate(request, filter.qs, 30, count=count) if category: ids = AddonCategory.creatured_random(category, request.LANG) featured = manual_order(base, ids, pk_name="addons.id") else: ids = Addon.featured_random(request.APP, request.LANG) featured = manual_order(base, ids, pk_name="addons.id") ctx = {'categories': categories, 'category': category, 'addons': addons, 'filter': filter, 'sorting': filter.field, 'sort_opts': filter.opts, 'featured': featured, 'search_cat': 'personas', 'is_homepage': category is None and 'sort' not in request.GET} return jingo.render(request, template, ctx)
def test_query_or_and(self): qs = Addon.search().query(or_=dict(type=1, status__gte=2), category=2) eq_(qs._build_query()['query']['function_score']['query'], {'bool': {'must': [{'term': {'category': 2}}, {'bool': {'should': [ {'term': {'type': 1}}, {'range': {'status': {'gte': 2}}}, ]}}]}})
def es_extensions(request, category=None, template=None): TYPE = amo.ADDON_EXTENSION if category is not None: q = Category.objects.filter(application=request.APP.id, type=TYPE) category = get_object_or_404(q, slug=category) if ('sort' not in request.GET and not request.MOBILE and category and category.count > 4): return category_landing(request, category) qs = (Addon.search().filter(type=TYPE, app=request.APP.id, is_disabled=False, status__in=amo.REVIEWED_STATUSES)) filter = ESAddonFilter(request, qs, key='sort', default='popular') qs, sorting = filter.qs, filter.field src = 'cb-btn-%s' % sorting dl_src = 'cb-dl-%s' % sorting if category: qs = qs.filter(category=category.id) addons = amo.utils.paginate(request, qs) return render(request, template, {'section': 'extensions', 'addon_type': TYPE, 'category': category, 'addons': addons, 'filter': filter, 'sorting': sorting, 'sort_opts': filter.opts, 'src': src, 'dl_src': dl_src, 'search_cat': '%s,0' % TYPE})
def create(self, request): if not waffle.flag_is_active(request, 'accept-webapps'): return rc.BAD_REQUEST form = NewManifestForm(request.POST) if form.is_valid(): # This feels like an awful lot of work. # But first upload the file and do the validation. upload = FileUpload.objects.create() tasks.fetch_manifest(form.cleaned_data['manifest'], upload.pk) # We must reget the object here since the above has # saved changes to the object. upload = FileUpload.uncached.get(pk=upload.pk) # Check it validated correctly. if settings.VALIDATE_ADDONS: validation = json.loads(upload.validation) if validation['errors']: response = rc.BAD_REQUEST response.write(validation) return response # Fetch the addon, the icon and set the user. addon = Addon.from_upload(upload, [Platform.objects.get(id=amo.PLATFORM_ALL.id)]) tasks.fetch_icon(addon) AddonUser(addon=addon, user=request.amo_user).save() addon.update(status=amo.STATUS_PENDING if settings.WEBAPPS_RESTRICTED else amo.STATUS_PUBLIC) else: return _form_error(form) return addon
def test_lt(self): qs = Addon.search().filter(type__in=[1, 2], status__lt=4) eq_(qs._build_query()['query']['filtered']['filter'], {'and': [ {'range': {'status': {'lt': 4}}}, {'in': {'type': [1, 2]}}, ]})
def queryset(self): """Get items based on ID or search by name.""" results = Addon.objects.none() q = self.request.GET.get(self.key) if q: pk = None try: pk = int(q) except ValueError: pass qs = None if pk: qs = Addon.objects.filter(id=int(q), disabled_by_user=False) elif len(q) > 2: # Oh, how I wish I could elastically exclude terms. # (You can now, but I forgot why I was complaining to # begin with.) qs = (Addon.search().query( or_=name_only_query(q.lower())).filter(is_disabled=False)) if qs: results = qs.filter(type__in=self.types, status__in=amo.REVIEWED_STATUSES) return results
def _personas(request): """Handle the request for persona searches.""" initial = dict(request.GET.items()) # Ignore these filters since return the same results for Firefox # as for Thunderbird, etc. initial.update(appver=None, platform=None) form = ESSearchForm(initial, type=amo.ADDON_PERSONA) form.is_valid() qs = Addon.search().filter(status__in=amo.REVIEWED_STATUSES, is_disabled=False) filters = ['sort'] mapping = {'downloads': '-weekly_downloads', 'users': '-average_daily_users', 'rating': '-bayesian_rating', 'created': '-created', 'name': 'name_sort', 'updated': '-last_updated', 'hotness': '-hotness'} results = _filter_search(request, qs, form.cleaned_data, filters, sorting=mapping, types=[amo.ADDON_PERSONA]) query = form.cleaned_data.get('q', '') search_opts = {} search_opts['limit'] = form.cleaned_data.get('pp', DEFAULT_NUM_PERSONAS) page = form.cleaned_data.get('page') or 1 search_opts['offset'] = (page - 1) * search_opts['limit'] pager = amo.utils.paginate(request, results, per_page=search_opts['limit']) categories, filter, _, _ = browse.views.personas_listing(request) c = dict(pager=pager, form=form, categories=categories, query=query, filter=filter, search_placeholder='personas') return jingo.render(request, 'search/personas.html', c)
def process_request(self, list_type='recommended', addon_type='ALL', limit=10, platform='ALL', version=None, compat_mode='strict'): """ Find a list of new or featured add-ons. Filtering is done in Python for cache-friendliness and to avoid heavy queries. """ limit = min(MAX_LIMIT, int(limit)) APP, platform = self.request.APP, platform.lower() qs = Addon.objects.listed(APP) shuffle = True if list_type in ('by_adu', 'featured'): qs = qs.exclude(type=amo.ADDON_PERSONA) if list_type == 'newest': new = date.today() - timedelta(days=NEW_DAYS) addons = (qs.filter(created__gte=new) .order_by('-created'))[:limit + BUFFER] elif list_type == 'by_adu': addons = qs.order_by('-average_daily_users')[:limit + BUFFER] shuffle = False # By_adu is an ordered list. elif list_type == 'hotness': # Filter to type=1 so we hit visible_idx. Only extensions have a # hotness index right now so this is not incorrect. addons = (qs.filter(type=amo.ADDON_EXTENSION) .order_by('-hotness'))[:limit + BUFFER] shuffle = False else: ids = Addon.featured_random(APP, self.request.LANG) addons = manual_order(qs, ids[:limit + BUFFER], 'addons.id') shuffle = False args = (addon_type, limit, APP, platform, version, compat_mode, shuffle) f = lambda: self._process(addons, *args) return cached_with(addons, f, map(encoding.smart_str, args))
def es_extensions(request, category=None, template=None): TYPE = amo.ADDON_EXTENSION if category is not None: q = Category.objects.filter(application=request.APP.id, type=TYPE) category = get_object_or_404(q, slug=category) if ('sort' not in request.GET and not request.MOBILE and category and category.count > 4): return category_landing(request, category) qs = (Addon.search().filter(type=TYPE, app=request.APP.id, is_disabled=False, status__in=amo.REVIEWED_STATUSES)) filter = ESAddonFilter(request, qs, key='sort', default='popular') qs, sorting = filter.qs, filter.field src = 'cb-btn-%s' % sorting dl_src = 'cb-dl-%s' % sorting if category: qs = qs.filter(category=category.id) addons = amo.utils.paginate(request, qs) return render( request, template, { 'section': 'extensions', 'addon_type': TYPE, 'category': category, 'addons': addons, 'filter': filter, 'sorting': sorting, 'sort_opts': filter.opts, 'src': src, 'dl_src': dl_src, 'search_cat': '%s,0' % TYPE })
def test_query_or(self): qs = Addon.search().query(or_=dict(type=1, status__gte=2)) eq_( qs._build_query(), { 'fields': ['id'], 'query': { 'bool': { 'should': [ { 'term': { 'type': 1 } }, { 'range': { 'status': { 'gte': 2 } } }, ] } } })
def test_query_multiple_and_range(self): qs = Addon.search().query(type=1, status__gte=1) eq_( qs._build_query(), { 'fields': ['id'], 'query': { 'bool': { 'must': [ { 'term': { 'type': 1 } }, { 'range': { 'status': { 'gte': 1 } } }, ] } } })
def test_slice(self): qs = Addon.search()[5:12] eq_(qs._build_query(), {'fields': ['id'], 'from': 5, 'size': 7})
def test_slice_stop_zero(self): qs = Addon.search()[:0] eq_(qs._build_query(), {'fields': ['id'], 'size': 0})
def test_job(self): for job in [cron.reindex_addons, cron.reindex_apps]: job() self.refresh() eq_(sorted(a.id for a in Addon.search()), sorted(a.id for a in self.apps + self.addons))
def test_count(self): p = amo.utils.ESPaginator(Addon.search(), 20) eq_(p._count, None) p.page(1) eq_(p.count, Addon.search().count())
def test_values_dict(self): qs = Addon.search().values_dict('name') eq_(qs._build_query(), {'fields': ['id', 'name']})
def test_order_by_asc(self): qs = Addon.search().order_by('rating') eq_(qs._build_query(), {'fields': ['id'], 'sort': ['rating']})
def test_count_uses_cached_results(self): qs = Addon.search() qs._results_cache = mock.Mock() qs._results_cache.count = mock.sentinel.count eq_(qs.count(), mock.sentinel.count)
def test_len(self): qs = Addon.search() qs._results_cache = [1] eq_(len(qs), 1)
def test_empty_values_dict_result(self): qs = Addon.search().values_dict() # Look for some of the keys we expect. for key in ('id', 'name', 'status', 'app'): assert key in qs[0].keys(), qs[0].keys()
def test_values_dict_result(self): addons = [{'id': a.id, 'slug': a.slug} for a in self._addons] qs = Addon.search().values_dict('slug').order_by('id') eq_(list(qs), list(addons))
def test_empty_values_dict(self): qs = Addon.search().values_dict() eq_(qs._build_query(), {})
def test_extra_values_dict(self): qs = Addon.search().extra(values_dict=['name']) eq_(qs._build_query(), {'fields': ['id', 'name']}) qs = Addon.search().values_dict('status').extra(values_dict=['name']) eq_(qs._build_query(), {'fields': ['id', 'status', 'name']})
user__email=settings.LANGPACK_OWNER_EMAIL).exists()): log.info('[@None] Skipping language pack "%s": ' 'not owned by %s' % (xpi, settings.LANGPACK_OWNER_EMAIL)) continue version = Version.from_upload(upload, addon, PLATFORMS) log.info('[@None] Updating language pack "%s" to version %s' % (xpi, data['version'])) else: if amo.VERSION_BETA.search(data['version']): log.error('[@None] Not creating beta version %s for new "%s" ' 'language pack' % (data['version'], xpi)) continue addon = Addon.from_upload(upload, PLATFORMS) AddonUser(addon=addon, user=owner).save() version = addon.versions.get() addon.status = amo.STATUS_PUBLIC if addon.default_locale.lower() == lang.lower(): addon.target_locale = addon.default_locale addon.save() log.info('[@None] Creating new "%s" language pack, version %s' % (xpi, data['version'])) # Version.from_upload will do this automatically, but only # if the add-on is already public, which it may not be in # the case of new add-ons
def test_es_paginator(self): qs = Addon.search() pager = amo.utils.paginate(self.request, qs) assert isinstance(pager.paginator, amo.utils.ESPaginator)
def test_object_result(self): qs = Addon.search().filter(id=self._addons[0].id)[:1] eq_(self._addons[:1], list(qs))
def test_values_result(self): addons = [(a.id, a.slug) for a in self._addons] qs = Addon.search().values('slug').order_by('id') eq_(list(qs), addons)
def test_object_result_slice(self): addon = self._addons[0] qs = Addon.search().filter(id=addon.id) eq_(addon, qs[0])
def test_extra_bad_key(self): with self.assertRaises(AssertionError): Addon.search().extra(x=1)
def test_getitem(self): addons = list(Addon.search()) eq_(addons[0], Addon.search()[0])
def test_indexed_count(self): # Did all the right addons get indexed? eq_( Addon.search().filter(type=1, is_disabled=False).count(), Addon.objects.filter(disabled_by_user=False, status__in=amo.VALID_STATUSES).count())
def search(request, tag_name=None, template=None): APP = request.APP types = (amo.ADDON_EXTENSION, amo.ADDON_THEME, amo.ADDON_DICT, amo.ADDON_SEARCH, amo.ADDON_LPAPP) category = request.GET.get('cat') if category == 'collections': extra_params = {'sort': {'newest': 'created'}} else: extra_params = None fixed = fix_search_query(request.GET, extra_params=extra_params) if fixed is not request.GET: return http.HttpResponsePermanentRedirect( urlparams(request.path, **fixed)) form = ESSearchForm(request.GET or {}) form.is_valid() # Let the form try to clean data. query = form.cleaned_data if tag_name: query['tag'] = tag_name if category == 'collections': return _collections(request) elif category == 'personas' or query.get('atype') == amo.ADDON_PERSONA: return _personas(request) sort, extra_sort = split_choices(form.sort_choices, 'created') if query.get('atype') == amo.ADDON_SEARCH: # Search add-ons should not be searched by ADU, so replace 'Users' # sort with 'Weekly Downloads'. sort, extra_sort = list(sort), list(extra_sort) sort[1] = extra_sort[1] del extra_sort[1] qs = (Addon.search().filter( status__in=amo.REVIEWED_STATUSES, is_disabled=False, app=APP.id).facet( tags={'terms': { 'field': 'tag' }}, platforms={'terms': { 'field': 'platform' }}, appversions={'terms': { 'field': 'appversion.%s.max' % APP.id }}, categories={'terms': { 'field': 'category', 'size': 200 }})) filters = ['atype', 'appver', 'cat', 'sort', 'tag', 'platform'] mapping = { 'users': '-average_daily_users', 'rating': '-bayesian_rating', 'created': '-created', 'name': 'name_sort', 'downloads': '-weekly_downloads', 'updated': '-last_updated', 'hotness': '-hotness' } qs = _filter_search(request, qs, query, filters, mapping, types=types) pager = amo.utils.paginate(request, qs) ctx = { 'is_pjax': request.META.get('HTTP_X_PJAX'), 'pager': pager, 'query': query, 'form': form, 'sort_opts': sort, 'extra_sort_opts': extra_sort, 'sorting': sort_sidebar(request, query, form), 'sort': query.get('sort'), } if not ctx['is_pjax']: facets = pager.object_list.facets ctx.update({ 'tag': tag_name, 'categories': category_sidebar(request, query, facets), 'platforms': platform_sidebar(request, query, facets), 'versions': version_sidebar(request, query, facets), 'tags': tag_sidebar(request, query, facets), }) return jingo.render(request, template, ctx)
def test_iter(self): qs = Addon.search().filter(type=1, is_disabled=False) eq_(len(qs), len(list(qs)))
def test_generate_filename_ja(self): f = File() f.version = Version(version='0.1.7') f.version.compatible_apps = (amo.FIREFOX, ) f.version.addon = Addon(name=u' フォクすけ といっしょ') eq_(f.generate_filename(), 'addon-0.1.7-fx.xpi')
def test_count(self): eq_(Addon.search().count(), 6)