diff --git a/apps/browse/templates/browse/creatured.html b/apps/browse/templates/browse/creatured.html new file mode 100644 index 0000000000..1a5ac3569e --- /dev/null +++ b/apps/browse/templates/browse/creatured.html @@ -0,0 +1,23 @@ +{% extends "browse/base_listing.html" %} + +{% block title %} + {{ page_title(_('{0}: Featured Add-ons')|f(category.name)) }} +{% endblock %} + +{% block content %} +
+ {{ breadcrumbs([(url('browse.extensions'), _('Extensions')), + (url('browse.extensions', category.slug), category.name), + (None, _('Featured Add-ons'))]) }} +

{{ _('{0}: Featured Add-ons')|f(category.name) }}

+
+ +{% endblock %} diff --git a/apps/browse/tests.py b/apps/browse/tests.py index 859f1035ee..75f4d37a9d 100644 --- a/apps/browse/tests.py +++ b/apps/browse/tests.py @@ -390,7 +390,7 @@ class TestCategoryPages(amo.tests.TestCase): def test_browsing_urls(self): """Every browse page URL exists.""" - for slug in amo.ADDON_SLUGS.values(): + for _, slug in amo.ADDON_SLUGS.items(): view = 'apps.list' if slug == 'apps' else 'browse.%s' % slug assert reverse(view) @@ -438,6 +438,27 @@ class TestCategoryPages(amo.tests.TestCase): creatured = response.context['filter'].all()['featured'] eq_(len(creatured), 0) + def test_creatured_only_public(self): + """Make sure the creatured add-ons are all public.""" + url = reverse('browse.creatured', args=['bookmarks']) + r = self.client.get(url, follow=True) + addons = r.context['addons'] + + for a in addons: + assert a.status == amo.STATUS_PUBLIC, "%s is not public" % a.name + + old_count = len(addons) + addons[0].status = amo.STATUS_UNREVIEWED + addons[0].save() + r = self.client.get(url, follow=True) + addons = r.context['addons'] + + for a in addons: + assert a.status == amo.STATUS_PUBLIC, ("Altered %s is featured" + % a.name) + + eq_(len(addons), old_count - 1, "The number of addons is the same.") + def test_sorting_nameless(self): """Nameless add-ons are dropped from the sort.""" qs = Addon.objects.all() @@ -446,31 +467,6 @@ class TestCategoryPages(amo.tests.TestCase): assert 57132 not in [a.id for a in ids] -@mock.patch.object(settings, 'NEW_FEATURES', True) -class TestNewCategoryPages(amo.tests.TestCase): - fixtures = ['base/apps', 'base/category', 'base/featured', - 'addons/featured', 'addons/listed', 'base/collections', - 'bandwagon/featured_collections'] - - def setUp(self): - self.reset_featured_addons() - - def test_creatured(self): - AddonCategory.objects.create(addon_id=2464, category_id=22) - url = urlparams(reverse('browse.extensions', args=['bookmarks']), - sort='featured') - r = self.client.get(url, follow=True) - addons = r.context['addons'] - eq_(len(addons), 1) - eq_(addons[0].status, amo.STATUS_PUBLIC) - - addons[0].update(status=amo.STATUS_UNREVIEWED) - eq_(addons[0].status, amo.STATUS_UNREVIEWED) - r = self.client.get(url, follow=True) - addons = r.context['addons'] - eq_(len(addons), 0) - - class TestFeeds(amo.tests.TestCase): fixtures = ['base/apps', 'base/category', 'base/featured', 'addons/featured', 'addons/listed', 'base/collections', @@ -1187,8 +1183,6 @@ class TestLegacyRedirects(amo.tests.TestCase): # redirects('/browse/type:7', '/plugins/') redirects('/recommended', '/extensions/?sort=featured') redirects('/featured', '/extensions/?sort=featured') - redirects('/extensions/alerts-updates/featured', - '/extensions/alerts-updates/?sort=featured') redirects('/recommended/format:rss', '/featured/format:rss') diff --git a/apps/browse/urls.py b/apps/browse/urls.py index 98b8e6f782..f45ecea6e1 100644 --- a/apps/browse/urls.py +++ b/apps/browse/urls.py @@ -7,6 +7,8 @@ from . import views impala_patterns = patterns('', # TODO: Impalacize these views. + url('^extensions/(?P[^/]+)/featured$', views.creatured, + name='i_browse.creatured'), url('^personas/(?P[^ /]+)?$', views.personas, name='i_browse.personas'), url('^language-tools/(?P[^/]+)?$', views.language_tools, @@ -33,9 +35,8 @@ urlpatterns = patterns('', url('^es/extensions/(?:(?P[^/]+)/)?$', views.es_extensions, name='browse.es.extensions'), - # Redirects for old creatured page. - url('^extensions/(?P[^/]+)/featured$', views.extensions, - {'creatured': True}), + url('^extensions/(?P[^/]+)/featured$', + views.creatured, name='browse.creatured'), url('^extensions/(?:(?P[^/]+)/)?format:rss$', CategoriesRss(), name='browse.extensions.rss'), diff --git a/apps/browse/views.py b/apps/browse/views.py index 14b03baa80..e0199b6d81 100644 --- a/apps/browse/views.py +++ b/apps/browse/views.py @@ -1,5 +1,7 @@ import collections +from django import http +from django.db.models import Q from django.http import HttpResponsePermanentRedirect from django.shortcuts import get_object_or_404 from django.views.decorators.cache import cache_page @@ -13,7 +15,6 @@ import amo import amo.models from amo.models import manual_order from amo.urlresolvers import reverse -from amo.utils import urlparams from addons.models import Addon, AddonCategory, Category, FrozenAddon from addons.utils import FeaturedManager, CreaturedManager from addons.views import BaseFilter, ESBaseFilter @@ -158,16 +159,12 @@ def themes(request, category=None): @mobile_template('browse/{mobile/}extensions.html') -def extensions(request, category=None, creatured=False, template=None): +def 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 creatured: - dst = urlparams(reverse('browse.extensions', args=[category.slug]), - sort='featured') - return HttpResponsePermanentRedirect(dst) sort = request.GET.get('sort') if not sort and not request.MOBILE and category and category.count > 4: @@ -202,6 +199,7 @@ def es_extensions(request, category=None, template=None): 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)) @@ -262,7 +260,6 @@ def category_landing(request, category, addon_type=amo.ADDON_EXTENSION, def es_category_landing(request, category): # TODO: Match CategoryLandingFilter. - TYPE = amo.ADDON_EXTENSION qs = (Addon.search().filter(type=TYPE, app=request.APP.id, is_disabled=False, status__in=amo.REVIEWED_STATUSES)) @@ -272,6 +269,17 @@ def es_category_landing(request, category): 'search_cat': '%s,0' % category.type}) +def creatured(request, category): + TYPE = amo.ADDON_EXTENSION + q = Category.objects.filter(application=request.APP.id, type=TYPE) + category = get_object_or_404(q, slug=category) + ids = AddonCategory.creatured_random(category, request.LANG) + addons = manual_order(Addon.objects.public(), ids) + return jingo.render(request, 'browse/creatured.html', + {'addons': addons, 'category': category, + 'sorting': 'featured'}) + + class PersonasFilter(BaseFilter): opts = (('up-and-coming', _lazy(u'Up & Coming')),