unleash consumer pages: a new home, a new hope (bug 743757)

This commit is contained in:
Chris Van 2012-04-09 18:45:03 -07:00
Родитель 1956ace3c0
Коммит 1a14fcb20f
18 изменённых файлов: 192 добавлений и 83 удалений

Просмотреть файл

@ -10,6 +10,7 @@ from django.utils import encoding
from django.utils.translation.trans_real import parse_accept_lang_header
import jinja2
import waffle
import amo
@ -134,7 +135,8 @@ class Prefixer(object):
url_parts.append(locale)
# Temporarily force home page to /<locale>/developers/.
if settings.MARKETPLACE and not path.partition('/')[0]:
if (not waffle.switch_is_active('unleash-consumer') and
settings.MARKETPLACE and not path.partition('/')[0]):
url_parts.append('developers')
elif path.partition('/')[0] not in settings.SUPPORTED_NONAPPS:

Просмотреть файл

@ -168,7 +168,8 @@
}
#slug_edit a {
font-size: 10px;
font-size: 11px;
font-weight: bold;
}
form .char-count,

Просмотреть файл

@ -0,0 +1,5 @@
INSERT INTO waffle_switch_mkt (name, active, note)
VALUES ('unleash-consumer', 0,
'This activates the consumer flow. No login. Home is really home, '
'not the Developer Hub. Stuff is pretty. This is for what you '
'have been waiting.');

Просмотреть файл

@ -297,8 +297,6 @@ class TestProfileLinks(amo.tests.TestCase):
def setUp(self):
self.user = self.get_user()
# Authentication is required for now.
assert self.client.login(username=self.user.email, password='password')
def get_user(self):
return UserProfile.objects.get(username='31337')
@ -306,6 +304,9 @@ class TestProfileLinks(amo.tests.TestCase):
def get_url(self):
return reverse('users.profile', args=[self.user.username])
def log_in(self):
assert self.client.login(username=self.user.email, password='password')
def test_id_or_username(self):
args = [self.user.id, self.user.username]
for arg in args:
@ -321,6 +322,7 @@ class TestProfileLinks(amo.tests.TestCase):
def test_viewing_my_profile(self):
# Me as (non-admin) viewing my own profile.
self.log_in()
links = self.get_profile_links(self.user.id)
eq_(links.length, 1)
eq_(links.eq(0).attr('href'), reverse('account.settings'))
@ -332,11 +334,18 @@ class TestProfileLinks(amo.tests.TestCase):
links = self.get_profile_links(self.user.id)
eq_(links.length, 0, 'No edit buttons should be shown.')
def test_viewing_my_profile_as_anonymous(self):
# Ensure no edit buttons are shown.
links = self.get_profile_links(self.user.id)
eq_(links.length, 0, 'No edit buttons should be shown.')
def test_viewing_other_profile(self):
self.log_in()
# Me as (non-admin) viewing someone else's my own profile.
eq_(self.get_profile_links(id=999).length, 0)
def test_viewing_my_profile_as_admin(self):
self.log_in()
# Me as (with admin) viewing my own profile.
GroupUser.objects.create(
group=Group.objects.create(rules='Users:Edit'), user=self.user)
@ -346,6 +355,7 @@ class TestProfileLinks(amo.tests.TestCase):
eq_(links.eq(0).attr('href'), reverse('account.settings'))
def test_viewing_other_profile_as_admin(self):
self.log_in()
# Me as (with admin) viewing someone else's profile.
GroupUser.objects.create(
group=Group.objects.create(rules='Users:Edit'), user=self.user)

Просмотреть файл

@ -29,12 +29,10 @@ purchases_patterns = decorate(login_required, patterns('',
name='account.purchases.receipt'),
))
users_patterns = decorate(login_required, patterns('',
users_patterns = patterns('',
# Keeping the same URL pattern since admin pages already know about this.
url(r'^(?:(?P<user_id>\d+)/)?edit$', views.admin_edit,
name='users.admin_edit'),
# TODO: Don't require authentication for this.
url(r'''(?P<username>[^/<>"']+)$''', views.profile,
name='users.profile'),
))
)

Просмотреть файл

@ -11,8 +11,8 @@ from tower import ugettext as _, ugettext_lazy as _lazy
from access import acl
from addons.views import BaseFilter
import amo
from amo.decorators import (login_required, no_login_required,
permission_required, post_required, write)
from amo.decorators import (login_required, permission_required, post_required,
write)
from amo.utils import paginate
from market.models import PreApprovalUser
import paypal
@ -174,6 +174,7 @@ def account_settings(request):
@write
@login_required
@permission_required('Users', 'Edit')
def admin_edit(request, user_id):
amouser = get_object_or_404(UserProfile, pk=user_id)
@ -209,7 +210,6 @@ def delete_photo(request):
return http.HttpResponse()
@no_login_required
def profile(request, username):
if username.isdigit():
user = get_object_or_404(UserProfile, id=username)

Просмотреть файл

@ -8,13 +8,15 @@ import jinja2
from jingo import register
from jingo.helpers import datetime
from tower import ugettext as _, ungettext as ngettext
import waffle
import amo
from amo.urlresolvers import reverse
from amo.helpers import breadcrumbs, impala_breadcrumbs, loc
from amo.helpers import breadcrumbs
from access import acl
from addons.helpers import new_context
from mkt.site.helpers import mkt_breadcrumbs
register.function(acl.check_addon_ownership)
@ -41,7 +43,7 @@ def hub_page_title(context, title=None, addon=None):
@jinja2.contextfunction
def mkt_page_title(context, title, force_webapps=False):
title = smart_unicode(title)
base_title = loc('Mozilla Marketplace')
base_title = _('Mozilla Marketplace')
return u'%s | %s' % (title, base_title)
@ -56,8 +58,7 @@ def docs_page_title(context, title=None):
@register.function
@jinja2.contextfunction
def hub_breadcrumbs(context, addon=None, items=None, add_default=False,
landing_galore=False):
def hub_breadcrumbs(context, addon=None, items=None, add_default=False):
"""
Wrapper function for ``breadcrumbs``. Prepends 'Developer Hub'
breadcrumbs.
@ -72,18 +73,18 @@ def hub_breadcrumbs(context, addon=None, items=None, add_default=False,
**impala**
Whether to use the impala_breadcrumbs helper. Default is False.
"""
if landing_galore:
if waffle.switch_is_active('unleash-consumer'):
crumbs = [(reverse('mkt.developers.index'), _('Developer Hub'))]
else:
crumbs = [(reverse('mkt.developers.apps'), _('My Submissions'))]
if landing_galore:
if waffle.switch_is_active('unleash-consumer'):
title = _('My Submissions')
link = reverse('mkt.developers.apps')
else:
title = link = None
if addon:
if landing_galore:
if waffle.switch_is_active('unleash-consumer'):
if not addon and not items:
# We are at the end of the crumb trail.
crumbs.append((None, title))
@ -101,7 +102,8 @@ def hub_breadcrumbs(context, addon=None, items=None, add_default=False,
if len(crumbs) == 1:
crumbs = []
return impala_breadcrumbs(context, crumbs, add_default)
return mkt_breadcrumbs(context, items=crumbs,
add_default=waffle.switch_is_active('unleash-consumer'))
@register.function

Просмотреть файл

@ -42,7 +42,11 @@
{{ form.slug.errors }}
{% else %}
{{ settings.SITE_URL }}/&hellip;/{{ addon.app_slug if webapp else addon.slug }}
<em class="edit-addon-details">{{ loc('(Not Available Yet)') }}</em>
{% if waffle.switch('unleash-consumer') %}
<a href="{{ addon.get_url_path() }}">{{ _('View Listing') }}</em>
{% else %}
<em class="edit-addon-details">{{ loc('(Not Available Yet)') }}</em>
{% endif %}
{% endif %}
</td>
</tr>

Просмотреть файл

@ -20,3 +20,13 @@
<link rel="stylesheet" href="{{ media('css/legacy/nojs.css') }}">
</noscript>
{% endblock %}
{% block aux_nav %}
{% if waffle.switch('unleash-consumer') %}
<li class="nomenu">
<a class="return" href="{{ url('home') }}">{{ _('Back to Apps') }}</a>
</li>
{% else %}
{{ super() }}
{% endif %}
{% endblock %}

Просмотреть файл

@ -21,6 +21,11 @@
(addon.get_dev_url('in_app_config'), _('Manage In-App Payments'))
) %}
{% endif %}
{% if waffle.switch('unleash-consumer') %}
{% do urls.append(
(addon.get_url_path(), _('View Listing'))
) %}
{% endif %}
<section class="secondary manage" role="complementary">
<div class="island" id="edit-addon-nav">

Просмотреть файл

@ -53,6 +53,7 @@
{% if not settings.READ_ONLY %}
{% include 'impala/user_login.html' %}
{% endif %}
{% block aux_nav %}{% endblock %}
</ul>
</nav>
{% block masthead %}

Просмотреть файл

@ -7,6 +7,7 @@ from django.utils import translation
from mock import Mock
from nose.tools import eq_
from pyquery import PyQuery as pq
import waffle
import amo
import amo.tests
@ -40,7 +41,7 @@ def test_hub_page_title():
eq_(s1, s2)
class TestDevBreadcrumbs(unittest.TestCase):
class TestLegacyDevBreadcrumbs(unittest.TestCase):
def setUp(self):
self.request = Mock()
@ -50,60 +51,119 @@ class TestDevBreadcrumbs(unittest.TestCase):
s = render('{{ hub_breadcrumbs() }}', {'request': self.request})
eq_(s, '')
def test_no_args_with_default(self):
s = render('{{ hub_breadcrumbs(add_default=True) }}',
{'request': self.request})
eq_(pq(s).text(), 'Add-ons')
def test_with_items(self):
s = render("""{{ hub_breadcrumbs(items=[('/foo', 'foo'),
('/bar', 'bar')]) }}'""",
{'request': self.request})
crumbs = pq(s)('li')
expected = [
('My Submissions', reverse('mkt.developers.apps')),
('foo', '/foo'),
('bar', '/bar'),
]
amo.tests.check_links(expected, crumbs, verify=False)
def test_with_app(self):
product = Mock()
product.name = 'Steamcube'
product.id = 9999
product.app_slug = 'scube'
product.type = amo.ADDON_WEBAPP
s = render("""{{ hub_breadcrumbs(product) }}""",
{'request': self.request, 'product': product})
crumbs = pq(s)('li')
expected = [
('My Submissions', reverse('mkt.developers.apps')),
('Steamcube', None),
]
amo.tests.check_links(expected, crumbs, verify=False)
def test_with_app_and_items(self):
product = Mock()
product.name = 'Steamcube'
product.id = 9999
product.app_slug = 'scube'
product.type = amo.ADDON_WEBAPP
product.get_dev_url.return_value = reverse('mkt.developers.apps.edit',
args=[product.app_slug])
s = render("""{{ hub_breadcrumbs(product,
items=[('/foo', 'foo'),
('/bar', 'bar')]) }}""",
{'request': self.request, 'product': product})
crumbs = pq(s)('li')
expected = [
('My Submissions', reverse('mkt.developers.apps')),
('Steamcube', product.get_dev_url()),
('foo', '/foo'),
('bar', '/bar'),
]
amo.tests.check_links(expected, crumbs, verify=False)
class TestNewDevBreadcrumbs(amo.tests.TestCase):
def setUp(self):
self.request = Mock()
self.request.APP = None
waffle.models.Switch.objects.create(name='unleash-consumer',
active=True)
def test_no_args(self):
s = render('{{ hub_breadcrumbs() }}', {'request': self.request})
eq_(s, '')
def test_with_items(self):
s = render("""{{ hub_breadcrumbs(items=[('/foo', 'foo'),
('/bar', 'bar')]) }}'""",
{'request': self.request})
doc = pq(s)
crumbs = doc('li>a')
eq_(len(crumbs), 3)
eq_(crumbs.eq(1).text(), 'foo')
eq_(crumbs.eq(1).attr('href'), '/foo')
eq_(crumbs.eq(2).text(), 'bar')
eq_(crumbs.eq(2).attr('href'), '/bar')
crumbs = pq(s)('li')
expected = [
('Home', reverse('home')),
('Developer Hub', reverse('mkt.developers.index')),
('foo', '/foo'),
('bar', '/bar'),
]
amo.tests.check_links(expected, crumbs, verify=False)
def test_with_app(self):
addon = Mock()
addon.name = 'Firebug'
addon.id = 1843
addon.app_slug = 'fbug'
addon.type = amo.ADDON_WEBAPP
s = render("""{{ hub_breadcrumbs(addon) }}""",
{'request': self.request, 'addon': addon})
doc = pq(s)
crumbs = doc('li')
eq_(crumbs.eq(0).text(), 'My Submissions')
eq_(crumbs.eq(0).children('a').attr('href'),
reverse('mkt.developers.apps'))
eq_(crumbs.eq(1).text(), 'Firebug')
eq_(crumbs.eq(1).children('a'), [])
product = Mock()
product.name = 'Steamcube'
product.id = 9999
product.app_slug = 'scube'
product.type = amo.ADDON_WEBAPP
s = render("""{{ hub_breadcrumbs(product) }}""",
{'request': self.request, 'product': product})
crumbs = pq(s)('li')
expected = [
('Home', reverse('home')),
('Developer Hub', reverse('mkt.developers.index')),
('My Submissions', reverse('mkt.developers.apps')),
('Steamcube', None),
]
amo.tests.check_links(expected, crumbs, verify=False)
def test_with_addon_and_items(self):
addon = Mock()
addon.name = 'Firebug'
addon.id = 1843
addon.app_slug = 'fbug'
addon.type = amo.ADDON_WEBAPP
addon.get_dev_url.return_value = reverse('mkt.developers.apps.edit',
args=[addon.app_slug])
s = render("""{{ hub_breadcrumbs(addon,
def test_with_app_and_items(self):
product = Mock()
product.name = 'Steamcube'
product.id = 9999
product.app_slug = 'scube'
product.type = amo.ADDON_WEBAPP
product.get_dev_url.return_value = reverse('mkt.developers.apps.edit',
args=[product.app_slug])
s = render("""{{ hub_breadcrumbs(product,
items=[('/foo', 'foo'),
('/bar', 'bar')]) }}""",
{'request': self.request, 'addon': addon})
doc = pq(s)
crumbs = doc('li')
eq_(len(crumbs), 4)
eq_(crumbs.eq(1).text(), 'Firebug')
eq_(crumbs.eq(1).children('a').attr('href'), addon.get_dev_url())
eq_(crumbs.eq(2).text(), 'foo')
eq_(crumbs.eq(2).children('a').attr('href'), '/foo')
eq_(crumbs.eq(3).text(), 'bar')
eq_(crumbs.eq(3).children('a').attr('href'), '/bar')
{'request': self.request, 'product': product})
crumbs = pq(s)('li')
expected = [
('Home', reverse('home')),
('Developer Hub', reverse('mkt.developers.index')),
('My Submissions', reverse('mkt.developers.apps')),
('Steamcube', product.get_dev_url()),
('foo', '/foo'),
('bar', '/bar'),
]
amo.tests.check_links(expected, crumbs, verify=False)
def test_summarize_validation():

Просмотреть файл

@ -91,6 +91,7 @@ def addon_listing(request, default='name', webapp=False):
@anonymous_csrf
# TODO: Remove when we flip `unleash-consumer`.
@no_login_required
def login(request, template=None):
return _login(request, template='developers/login.html')
@ -602,6 +603,7 @@ def upload(request, addon_slug=None, is_standalone=False):
else:
return redirect('mkt.developers.upload_detail', fu.pk, 'json')
def trap_duplicate(manifest_url):
apps = Webapp.objects.filter(manifest_url=manifest_url)
if not apps:
@ -612,17 +614,18 @@ def trap_duplicate(manifest_url):
return _('Oops, looks like you already submitted that manifest '
'for %s, which is currently public. '
'<a href="%s">Edit app</a>'
) % (app.name, error_url)
) % (app.name, error_url)
elif app.status in [amo.STATUS_PENDING, amo.STATUS_NOMINATED]:
return _('Oops, looks like you already submitted that manifest '
'for %s, which is currently pending. '
'<a href="%s">Edit app</a>'
) % (app.name, error_url)
) % (app.name, error_url)
elif app.status in [amo.STATUS_NULL, amo.STATUS_DISABLED]:
return _('Oops, looks like you already submitted that manifest '
'for %s, which is currently incomplete. '
'<a href="%s">Resume app</a>'
) % (app.name, error_url)
) % (app.name, error_url)
@login_required
@post_required

Просмотреть файл

@ -3,6 +3,7 @@ import os
from lib.settings_base import *
from mkt import asset_bundles
# We'll soon need a `settings_test_mkt` to override this.
APP_PREVIEW = True
@ -11,10 +12,6 @@ WAFFLE_TABLE_SUFFIX = 'mkt'
# So temporary. Allow us to link to new devhub URLs from `Addon.get_dev_url()`.
MARKETPLACE = True
# Pretty temporary. Set the correct home for Marketplace. Redirects are sick!
#HOME = 'mkt.home.views.home'
HOME = 'mkt.developers.views.home'
# 403 view to render for CSRF failures.
CSRF_FAILURE_VIEW = 'mkt.site.views.csrf_failure'
@ -59,7 +56,7 @@ INSTALLED_APPS += (
'devhub', # Put here so helpers.py doesn't get loaded first.
)
SUPPORTED_NONAPPS += (
# this line is here until bug 735120 is fixed.
'', # Can you tell I'm really putting off bug 735120?
'app',
'apps',
'dev',
@ -91,6 +88,7 @@ MIDDLEWARE_CLASSES = list(MIDDLEWARE_CLASSES)
# MIDDLEWARE_CLASSES.remove('cake.middleware.CookieCleaningMiddleware')
MIDDLEWARE_CLASSES += (
'mkt.site.middleware.VaryOnAJAXMiddleware',
# TODO: Remove when we flip `unleash-consumer`.
'amo.middleware.NoConsumerMiddleware',
)
@ -135,6 +133,7 @@ NO_CONSUMER_MODULES = (
'sharing.views',
'tags.views',
'versions.views',
'mkt.account.profile',
'mkt.webapps.views',
)

Просмотреть файл

@ -81,8 +81,8 @@ def promo_slider(context, products):
@register.function
@jinja2.contextfunction
def mkt_breadcrumbs(context, product=None, items=None, add_default=False,
crumb_size=40):
def mkt_breadcrumbs(context, product=None, items=None, crumb_size=40,
add_default=True):
"""
Wrapper function for ``breadcrumbs``.
@ -94,7 +94,10 @@ def mkt_breadcrumbs(context, product=None, items=None, add_default=False,
**add_default**
Prepends trail back to home when True. Default is False.
"""
crumbs = [(reverse('home'), _('Home'))]
if add_default:
crumbs = [(reverse('home'), _('Home'))]
else:
crumbs = []
if product:
if items:
@ -111,7 +114,7 @@ def mkt_breadcrumbs(context, product=None, items=None, add_default=False,
crumbs = [(url_, truncate(label, crumb_size)) for (url_, label) in crumbs]
t = env.get_template('site/helpers/breadcrumbs.html').render(
breadcrumbs=crumbs, has_home=add_default)
breadcrumbs=crumbs)
return jinja2.Markup(t)

Просмотреть файл

@ -6,7 +6,7 @@
{% for target, label in breadcrumbs %}
<li>
{% if target %}
{% if loop.first and has_home %}
{% if loop.first %}
<a href="{{ target }}" class="home" title="{{ label }}">{{ label }}</a>
{% else %}
<a href="{{ target }}">{{ label }}</a>

Просмотреть файл

@ -30,6 +30,7 @@ def csrf_failure(request, reason=''):
status=403)
# TODO: Remove when we flip `unleash-consumer`.
@no_login_required
def manifest(request):
ctx = RequestContext(request)
@ -53,6 +54,7 @@ def manifest(request):
mimetype='application/x-web-app-manifest+json')
# TODO: Remove when we flip `unleash-consumer`.
@no_login_required
def robots(request):
"""Generate a robots.txt"""

Просмотреть файл

@ -5,13 +5,14 @@ from django.shortcuts import redirect
from django.views.decorators.cache import cache_page
from django.views.i18n import javascript_catalog
import waffle
from apps.users.views import logout
from apps.users.urls import (detail_patterns as user_detail_patterns,
users_patterns as users_users_patterns)
from mkt.account.urls import (purchases_patterns, settings_patterns,
users_patterns as mkt_users_patterns)
from mkt.developers.views import login
from mkt.home.views import home
admin.autodiscover()
@ -21,12 +22,15 @@ handler500 = 'mkt.site.views.handler500'
APP_SLUG = r"""(?P<app_slug>[^/<>"']+)"""
if waffle.switch_is_active('unleash-consumer'):
HOME = 'mkt.home.views.home'
else:
HOME = 'mkt.developers.views.home'
urlpatterns = patterns('',
# Home.
url('^$', settings.HOME, name='home'),
# The real home.
url('^home/$', home, name='mkt.home'),
url('^$', HOME, name='home'),
# App Detail pages.
('^app/%s/' % APP_SLUG, include('mkt.detail.urls')),