def test_redirect_after_login(self): url = urlparams(self._get_login_url(), to="/en-US/firefox/about") r = self.client.post(url, {'username': '******', 'password': '******'}, follow=True) self.assert3xx(r, '/en-US/about') url = urlparams(self._get_login_url(), to="/addon/new", domain="builder") r = self.client.post(url, {'username': '******', 'password': '******'}, follow=True) to, code = r.redirect_chain[0] self.assertEqual(to, 'https://builder.addons.mozilla.org/addon/new') self.assertEqual(code, 302)
def check_sort_links(self, key, title=None, sort_by=None, reverse=True, params=None): if params is None: params = {} response = self.client.get(urlparams(self.url, sort=key, **params)) assert response.status_code == 200 doc = pq(response.content) if title: if hasattr(self, 'MOBILE'): menu = doc('#sort-menu') assert menu.find('span').text() == title assert menu.find('.selected').text() == title else: assert doc('#sorter .selected').text() == title if sort_by: results = response.context['pager'].object_list if sort_by == 'name': expected = sorted(results, key=lambda x: unicode(x.name)) else: expected = sorted(results, key=lambda x: getattr(x, sort_by), reverse=reverse) assert list(results) == expected
def test_updated_timestamp(self): self._generate() r = self.client.get(urlparams(self.url, sort='updated')) items = pq(r.content)('.primary .item') for idx, c in enumerate(r.context['pager'].object_list): assert trim_whitespace(items.eq(idx).find('.modified').text()) == ( 'Updated %s' % trim_whitespace(datetime_filter(c.modified)))
def test_results_popularity(self): personas = [ ('Harry Potter', 2000), ('Japanese Koi Tattoo', 67), ('Japanese Tattoo', 250), ('Japanese Tattoo boop', 50), ('Japanese Tattoo ballin', 200), ('The Japanese Tattooed Girl', 242), ] for name, popularity in personas: self._addons.append(amo.tests.addon_factory(name=name, type=amo.ADDON_PERSONA, popularity=popularity)) self.refresh() # Japanese Tattoo should be the #1 most relevant result. Obviously. expected_name, expected_popularity = personas[2] for sort in ('downloads', 'popularity', 'users'): r = self.client.get(urlparams(self.url, q='japanese tattoo', sort=sort), follow=True) assert r.status_code == 200 results = list(r.context['pager'].object_list) first = results[0] assert unicode(first.name) == expected_name, ( 'Was not first result for %r. Results: %s' % (sort, results)) assert first.persona.popularity == expected_popularity, ( 'Incorrect popularity for %r. Got %r. Expected %r.' % ( sort, first.persona.popularity, results)) assert first.average_daily_users == expected_popularity, ( 'Incorrect users for %r. Got %r. Expected %r.' % ( sort, first.average_daily_users, results)) assert first.weekly_downloads == expected_popularity, ( 'Incorrect weekly_downloads for %r. Got %r. Expected %r.' % ( sort, first.weekly_downloads, results))
def test_upandcoming_sort(self): r = self.client.get(urlparams(self.url, sort='hotness')) sel = pq(r.content)('#sorter ul > li.selected') assert sel.find('a').attr('class') == 'extra-opt' assert sel.text() == 'Up & Coming' a = r.context['addons'].object_list assert list(a) == sorted(a, key=lambda x: x.hotness, reverse=True)
def check_followers_count(self, sort, column): # Checks that we show the correct type/number of followers. r = self.client.get(urlparams(self.url, sort=sort)) items = pq(r.content)('.primary .item') for idx, c in enumerate(r.context['pager'].object_list): assert items.eq(idx).find('.followers').text().split()[0] == ( numberfmt(getattr(c, column)))
def test_updated_sort(self): r = self.client.get(urlparams(self.url, sort='updated')) sel = pq(r.content)('#sorter ul > li.selected') assert sel.find('a').attr('class') == 'extra-opt' assert sel.text() == 'Recently Updated' a = r.context['addons'].object_list assert list(a) == sorted(a, key=lambda x: x.last_updated, reverse=True)
def test_name_sort(self): r = self.client.get(urlparams(self.url, sort='name')) sel = pq(r.content)('#sorter ul > li.selected') assert sel.find('a').attr('class') == 'extra-opt' assert sel.text() == 'Name' a = r.context['addons'].object_list assert list(a) == sorted(a, key=lambda x: x.name)
def test_created_timestamp(self): self._generate() r = self.client.get(urlparams(self.url, sort='created')) items = pq(r.content)('.primary .item') for idx, c in enumerate(r.context['pager'].object_list): eq_(strip_whitespace(items.eq(idx).find('.modified').text()), 'Added %s' % strip_whitespace(datetime_filter(c.created)))
def check_sort_links(self, key, title=None, sort_by=None, reverse=True, params={}): r = self.client.get(urlparams(self.url, sort=key, **params)) eq_(r.status_code, 200) doc = pq(r.content) if title: if hasattr(self, 'MOBILE'): menu = doc('#sort-menu') eq_(menu.find('span').text(), title) eq_(menu.find('.selected').text(), title) else: eq_(doc('#sorter .selected').text(), title) if sort_by: results = r.context['pager'].object_list if sort_by == 'name': expected = sorted(results, key=lambda x: unicode(x.name)) else: expected = sorted(results, key=lambda x: getattr(x, sort_by), reverse=reverse) eq_(list(results), expected)
def test_users_adu_unit(self): doc = pq(self.client.get(urlparams(self.url, sort='users')).content) for item in doc('.items .item'): item = pq(item) addon_id = item('.install').attr('data-addon') adu = Addon.objects.get(id=addon_id).average_daily_users assert item('.adu').text() == ( '%s user%s' % (numberfmt(adu), 's' if adu != 1 else ''))
def test_updated_date(self): doc = pq(self.client.get(urlparams(self.url, sort='updated')).content) for item in doc('.items .item'): item = pq(item) addon_id = item('.install').attr('data-addon') ts = Addon.objects.get(id=addon_id).last_updated assert item('.updated').text() == ( u'Updated %s' % trim_whitespace(datetime_filter(ts)))
def test_redirect_after_login_evil(self): url = urlparams(self._get_login_url(), to='http://foo.com') r = self.client.post(url, { 'username': '******', 'password': '******' }, follow=True) self.assert3xx(r, '/en-US/firefox/')
def test_results_popularity(self): collections = [ ('Traveler Pack', 2000), ] webdev_collections = [ ('Tools for Developer', 67), ('Web Developer', 250), ('Web Developer Necessities', 50), ('Web Pro', 200), ('Web Developer Pack', 242), ] sorted_webdev_collections = sorted(webdev_collections, key=lambda x: x[1], reverse=True) # Create collections, in "random" order, with an additional collection # that isn't relevant to our query. for name, subscribers in (collections + webdev_collections): self._collections.append( amo.tests.collection_factory(name=name, subscribers=subscribers, weekly_subscribers=subscribers)) self.refresh() # No sort = sort by weekly subscribers, 'all' = sort by subscribers. for sort in ('', 'all'): if sort: r = self.client.get(urlparams(self.url, q='web developer', sort=sort), follow=True) else: r = self.client.get(urlparams(self.url, q='web developer'), follow=True) eq_(r.status_code, 200) results = list(r.context['pager'].object_list) eq_(len(results), len(webdev_collections)) for coll, expected in zip(results, sorted_webdev_collections): eq_( unicode(coll.name), expected[0], 'Wrong order for sort %r. Got: %s, expected: %s' % (sort, results, sorted_webdev_collections)) eq_( coll.subscribers, expected[1], 'Incorrect subscribers for %r. Got %s. Expected %s.' % (sort, coll.subscribers, expected[1]))
def check_cat_filters(self, params=None, selected='All Add-ons'): if not params: params = {} r = self.client.get(urlparams(self.url, **params)) assert sorted(a.id for a in self.addons) == ( sorted(a.id for a in r.context['pager'].object_list)) cat = self.addons[0].all_categories[0] links = pq(r.content)('#category-facets li a') expected = [ ('All Add-ons', self.url), ('Extensions', urlparams(self.url, atype=amo.ADDON_EXTENSION)), (unicode(cat.name), urlparams(self.url, atype=amo.ADDON_EXTENSION, cat=cat.id)), ] amo.tests.check_links(expected, links, selected, verify=False)
def test_toprated_sort(self): r = self.client.get(urlparams(self.url, sort='rating')) sel = pq(r.content)('#sorter ul > li.selected') assert sel.find('a').attr('class') == 'opt' assert sel.text() == 'Top Rated' a = r.context['addons'].object_list assert list(a) == sorted(a, key=lambda x: x.bayesian_rating, reverse=True)
def test_weeklydownloads_sort(self): r = self.client.get(urlparams(self.url, sort='popular')) sel = pq(r.content)('#sorter ul > li.selected') assert sel.find('a').attr('class') == 'extra-opt' assert sel.text() == 'Weekly Downloads' a = r.context['addons'].object_list assert list(a) == sorted(a, key=lambda x: x.weekly_downloads, reverse=True)
def test_popular_adu_unit(self): doc = pq(self.client.get(urlparams(self.url, sort='popular')).content) for item in doc('.items .item'): item = pq(item) addon_id = item('.install').attr('data-addon') adu = Addon.objects.get(id=addon_id).weekly_downloads assert item('.adu').text() == ( '%s weekly download%s' % (numberfmt(adu), 's' if adu != 1 else ''))
def test_unreviewed(self): pop = urlparams(self.url, sort='popular') # Only 3 without unreviewed. response = self.client.get(pop) assert len(response.context['addons'].object_list) == 2 response = self.client.get(pop) assert len(response.context['addons'].object_list) == 2
def test_mostusers_sort(self): r = self.client.get(urlparams(self.url, sort='users')) sel = pq(r.content)('#sorter ul > li.selected') assert sel.find('a').attr('class') == 'opt' assert sel.text() == 'Most Users' a = r.context['addons'].object_list assert list(a) == (sorted(a, key=lambda x: x.average_daily_users, reverse=True))
def test_cat_facet_stale(self): AddonCategory.objects.all().delete() r = self.client.get(self.url) expected = [ ('All Add-ons', self.url), ('Extensions', urlparams(self.url, atype=amo.ADDON_EXTENSION)), ] amo.tests.check_links(expected, pq(r.content)('#category-facets li a'), verify=False)
def setUp(self): super(TestFeaturedLocale, self).setUp() self.addon = Addon.objects.get(pk=3615) self.persona = Addon.objects.get(pk=15679) self.extension = Addon.objects.get(pk=2464) self.category = Category.objects.get(slug='bookmarks') self.url = urlparams(reverse('browse.extensions', args=['bookmarks']), {}, sort='featured') cache.clear()
def test_redirect(self): self.client.login(email='*****@*****.**') self.client.get('/', follow=True) url = '/en-US/about' r = self.client.get(urlparams(reverse('users.logout'), to=url), follow=True) self.assert3xx(r, url, status_code=302) url = urlparams(reverse('users.logout'), to='/addon/new', domain='builder') r = self.client.get(url, follow=True) to, code = r.redirect_chain[0] assert to == 'https://builder.addons.mozilla.org/addon/new' assert code == 302 # Test an invalid domain url = urlparams(reverse('users.logout'), to='/en-US/about', domain='http://evil.com') r = self.client.get(url, follow=True) self.assert3xx(r, '/en-US/about', status_code=302)
def build_list(self): """Populate a list of dictionaries based on label => property.""" results = [] for item in self.queryset()[:self.limit]: if item.id in self.excluded_ids: continue d = self._build_fields(item, self.fields) if self.src and 'url' in d: d['url'] = urlparams(d['url'], src=self.src) results.append(d) return results
def test_redirect_after_login(self): url = urlparams(self._get_login_url(), to="/en-US/firefox/about") r = self.client.post(url, { 'username': '******', 'password': '******' }, follow=True) self.assert3xx(r, '/en-US/about') url = urlparams(self._get_login_url(), to="/addon/new", domain="builder") r = self.client.post(url, { 'username': '******', 'password': '******' }, follow=True) to, code = r.redirect_chain[0] assert to == 'https://builder.addons.mozilla.org/addon/new' assert code == 302
def test_results_popularity(self): collections = [ ('Traveler Pack', 2000), ] webdev_collections = [ ('Tools for Developer', 67), ('Web Developer', 250), ('Web Developer Necessities', 50), ('Web Pro', 200), ('Web Developer Pack', 242), ] sorted_webdev_collections = sorted( webdev_collections, key=lambda x: x[1], reverse=True) # Create collections, in "random" order, with an additional collection # that isn't relevant to our query. for name, subscribers in (collections + webdev_collections): self._collections.append( amo.tests.collection_factory( name=name, subscribers=subscribers, weekly_subscribers=subscribers)) self.refresh() # No sort = sort by weekly subscribers, 'all' = sort by subscribers. for sort in ('', 'all'): if sort: r = self.client.get(urlparams(self.url, q='web developer', sort=sort), follow=True) else: r = self.client.get(urlparams(self.url, q='web developer'), follow=True) eq_(r.status_code, 200) results = list(r.context['pager'].object_list) eq_(len(results), len(webdev_collections)) for coll, expected in zip(results, sorted_webdev_collections): eq_(unicode(coll.name), expected[0], 'Wrong order for sort %r. Got: %s, expected: %s' % ( sort, results, sorted_webdev_collections)) eq_(coll.subscribers, expected[1], 'Incorrect subscribers for %r. Got %s. Expected %s.' % ( sort, coll.subscribers, expected[1]))
def test_tag_filters_on_search_page(self): Tag(tag_text='sky').save_tag(self.addons[0]) Tag(tag_text='sky').save_tag(self.addons[1]) Tag(tag_text='sky').save_tag(self.addons[2]) Tag(tag_text='earth').save_tag(self.addons[0]) Tag(tag_text='earth').save_tag(self.addons[1]) Tag(tag_text='ocean').save_tag(self.addons[0]) self.reindex(Addon) response = self.client.get(self.url, {'tag': 'sky'}) assert response.status_code == 200 assert self.get_results(response) # Tags filter UI should show 4 items ("All Tags" + 3 different tags) tags_links = pq(response.content)('#tag-facets li a[data-params]') assert len(tags_links) == 4 # First link should be "All Tags". assert tags_links[0].attrib['href'] == self.url assert json.loads(tags_links[0].attrib['data-params']) == { 'tag': None, 'page': None } # Then we should have the tags. expected_tags = ('sky', 'earth', 'ocean') for index, link in enumerate(tags_links[1:]): tag_text = expected_tags[index] assert link.attrib['href'] == urlparams(self.url, tag=tag_text) assert json.loads(link.attrib['data-params']) == { 'tag': tag_text, 'page': None } # Selected tag should be the one we passed in the URL: 'sky'. link = pq(response.content)('#tag-facets li.selected a[data-params]') assert json.loads(link.attr('data-params')) == { 'tag': 'sky', 'page': None }
def file_details(self, file): platform = file.platform if self.latest and not self.is_beta and ( self.addon.status == file.status == amo.STATUS_PUBLIC): url = file.latest_xpi_url() elif self.latest and self.is_beta and self.addon.show_beta: url = file.latest_xpi_url(beta=True) else: url = file.get_url_path(self.src) if platform == amo.PLATFORM_ALL.id: text, os = ugettext('Download Now'), None else: text, os = ugettext('Download'), amo.PLATFORMS[platform] if self.show_contrib: # L10n: please keep in the string so → does not wrap. text = jinja2.Markup(ugettext('Continue to Download →')) roadblock = reverse('addons.roadblock', args=[self.addon.id]) url = urlparams(roadblock, version=self.version.version) return text, url, os
def file_details(self, file): platform = file.platform if self.latest and not self.is_beta and ( self.addon.status == file.status == amo.STATUS_PUBLIC): url = file.latest_xpi_url() elif self.latest and self.is_beta and self.addon.show_beta: url = file.latest_xpi_url(beta=True) else: url = file.get_url_path(self.src) if platform == amo.PLATFORM_ALL.id: text, os = _('Download Now'), None else: text, os = _('Download'), amo.PLATFORMS[platform] if self.show_contrib: # L10n: please keep in the string so → does not wrap. text = jinja2.Markup(_('Continue to Download →')) roadblock = reverse('addons.roadblock', args=[self.addon.id]) url = urlparams(roadblock, version=self.version.version) return text, url, os
def login_url(self, **params): return absolutify(urlparams(reverse('users.login'), **params))
def migrate_path(next_path=None): return urlparams(reverse('users.migrate'), to=next_path)
def login_url(self, **params): return urlparams(reverse('users.login'), **params)
def test_legacy_redirect(self): self._generate() # Ensure `sort=newest` redirects to `sort=created`. r = self.client.get(urlparams(self.url, sort='newest')) self.assert3xx(r, urlparams(self.url, sort='created'), 301)
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)) facets = request.GET.copy() # In order to differentiate between "all versions" and an undefined value, # we use "any" instead of "" in the frontend. if 'appver' in facets and facets['appver'] == 'any': facets['appver'] = '' form = ESSearchForm(facets or {}) form.is_valid() # Let the form try to clean data. form_data = form.cleaned_data if tag_name: form_data['tag'] = tag_name if category == 'collections': return _collections(request) elif category == 'themes' or form_data.get('atype') == amo.ADDON_PERSONA: return _personas(request) sort, extra_sort = split_choices(form.sort_choices, 'created') if form_data.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] # Perform search, using aggregation so that we can build the facets UI. # Note that we don't need to aggregate on platforms, that facet it built # from our constants directly, using the current application for this # request (request.APP). qs = (Addon.search_public().filter(app=APP.id) .aggregate(tags={'terms': {'field': 'tags'}}, 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, form_data, filters, mapping, types=types) pager = amo.utils.paginate(request, qs) ctx = { 'is_pjax': request.META.get('HTTP_X_PJAX'), 'pager': pager, 'query': form_data, 'form': form, 'sort_opts': sort, 'extra_sort_opts': extra_sort, 'sorting': sort_sidebar(request, form_data, form), 'sort': form_data.get('sort'), } if not ctx['is_pjax']: aggregations = pager.object_list.aggregations ctx.update({ 'tag': tag_name, 'categories': category_sidebar(request, form_data, aggregations), 'platforms': platform_sidebar(request, form_data), 'versions': version_sidebar(request, form_data, aggregations), 'tags': tag_sidebar(request, form_data, aggregations), }) return render(request, template, ctx)
def check_name_results(self, params, expected): r = self.client.get(urlparams(self.url, **params), follow=True) assert r.status_code == 200 got = self.get_results(r) assert got == expected
def setUp(self): super(TestCollectionSearch, self).setUp() self.url = urlparams(reverse('search.search'), cat='collections') self.all_collections = []
def fix_link(self, url): if self.src: url = urlparams(url, src=self.src) if self.collection: url = urlparams(url, collection_id=self.collection) return url
def _make_download_url(self, view_name, src): from olympia.amo.helpers import urlparams, absolutify url = os.path.join(reverse(view_name, args=[self.pk]), self.filename) return absolutify(urlparams(url, src=src))
def test_unknown_tag_filter(self): r = self.client.get(urlparams(self.url, tag='xxx')) a = pq(r.content)('#tag-facets li.selected a') assert a.length == 1 assert a.text() == 'xxx' assert list(r.context['pager'].object_list) == []
def test_unknown_tag_filter(self): r = self.client.get(urlparams(self.url, tag='xxx')) a = pq(r.content)('#tag-facets li.selected a') eq_(a.length, 1) eq_(a.text(), 'xxx') eq_(list(r.context['pager'].object_list), [])
def test_search_space(self): r = self.client.get(urlparams(self.url, q='+')) assert r.status_code == 200
def test_mobile_results_downloads(self): r = self.client.get(urlparams(self.url, sort='downloads')) assert pq(r.content)('#content .item .vital.downloads'), ( 'Expected weekly downloads')
def setUp(self): super(TestPersonaSearch, self).setUp() self.url = urlparams(reverse('search.search'), atype=amo.ADDON_PERSONA)
def test_search_space(self): r = self.client.get(urlparams(self.url, q='+')) eq_(r.status_code, 200)
def check_name_results(self, params, expected): r = self.client.get(urlparams(self.url, **params), follow=True) eq_(r.status_code, 200) got = self.get_results(r) eq_(got, expected, 'Got: %s. Expected: %s. Parameters: %s' % (got, expected, params))