Fix bug 1102955: Use old contribute form for most locales on new page.

Allow us to enable the new contribute pages for all locales
without having to wait for new ET-based responders to be setup.
This commit is contained in:
Paul McLanahan 2014-11-20 23:29:01 -05:00
Родитель d1403eac5b
Коммит bc64aa0eda
15 изменённых файлов: 469 добавлений и 189 удалений

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

@ -6,7 +6,7 @@
{% from "newsletter/includes/macros.html" import email_form_thankyou with context %}
{% add_lang_files "mozorg/contribute" "mozorg/contribute/index" %}
{% add_lang_files "mozorg/contribute/index" %}
{% block body_class %}{{ super() }} contribute{% endblock %}
@ -18,7 +18,7 @@
{{ js('contribute-2015') }}
{% endblock %}
{% if l10n_has_tag('contribute_2015') %}
{% if l10n_has_tag('active', 'mozorg/contribute/index') %}
{% block site_header_nav %}{% endblock %}
{% block site_header_logo %}{% endblock %}
{% endif %}
@ -26,7 +26,7 @@
{% block content %}
<main role="main">
{% if l10n_has_tag('contribute_2015') %}
{% if l10n_has_tag('active', 'mozorg/contribute/index') %}
{% block contrib_head %}
<header class="page-head">
<div class="contribute-masthead">
@ -107,7 +107,7 @@
{% block contrib_content %}{% endblock contrib_content %}
{% if l10n_has_tag('contribute_2015') %}
{% if l10n_has_tag('active', 'mozorg/contribute/index') %}
{% block contrib_footer %}
<section class="section contrib-extra">
<div class="container">

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

@ -42,9 +42,11 @@
{% if contribute_success and return_to_form %} style="display:none"{% endif %}>
<fieldset>
<div class="row">
<div class="form-column-1">
<h3>{{_('Want to help?')}}</h3>
</div>
{% if not is_old_form %}
<div class="form-column-1">
<h3>{{_('Want to help?')}}</h3>
</div>
{% endif %}
<div class="form-column-2">
<div class="field field-interest">
{{ form.interest|safe }}

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

@ -0,0 +1,27 @@
{# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/. -#}
{% extends "mozorg/base-resp.html" %}
{% from "newsletter/includes/macros.html" import email_form_thankyou with context %}
{% add_lang_files "mozorg/contribute" %}
{% block body_class %}{{ super() }} contribute{% endblock %}
{% block page_css %}
{{ css('contribute-2015') }}
{% endblock %}
{% block js %}
{{ js('contribute-2015') }}
{% endblock %}
{% block content %}
<main role="main">
{% block contrib_content %}{% endblock contrib_content %}
</main>
{% endblock content %}
{% block email_form %}{% endblock %}

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

@ -2,7 +2,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/. -#}
{% extends "mozorg/contribute/contribute-base.html" %}
{% extends "mozorg/contribute/contribute-old-base.html" %}
{% add_lang_files "mozorg/contribute" %}

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

@ -1,155 +0,0 @@
{# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/. -#}
{% extends "mozorg/contribute/contribute-base.html" %}
{% add_lang_files "mozorg/contribute/index" %}
{% block page_title %}
{{ _('Volunteer Opportunities at Mozilla') }}
{% endblock %}
{% block js %}
{{ js('contribute-2015-landing') }}
{{ js('contribute-2015') }}
{% endblock %}
{% block body_id %}landing{% endblock %}
{% block contrib_nav_cta %}{% endblock %}
{% block contrib_page_title %}{{ _('Volunteer with Mozilla!') }}{% endblock %}
{% block contrib_content %}
<section id="landing-intro" class="section landing-intro">
<div id="slideshow" class="cycle-slideshow" data-cycle-speed="1000" data-cycle-timeout="6000" data-cycle-slides="> .slide" data-cycle-fx="fade" data-cycle-pause-on-hover="false" data-cycle-log="false">
<div class="slide slide-one">
<div class="container">
<p class="section-title">{{ _('Join a global community of game-changers.') }}</p>
</div>
</div>
<div class="slide slide-two">
<div class="container">
{# L10n: this br is for formatting, omit or reposition as needed #}
<p class="section-title">{{ _('Volunteer as much as you like. Or as little.<br> Its totally up to you.') }}</p>
</div>
</div>
<div class="slide slide-three">
<div class="container">
{# L10n: this br is for formatting, omit or reposition as needed #}
<p class="section-title">{{ _('Share your skills and pick up<br> a few new ones along the way.') }}</p>
</div>
</div>
<p class="cta"><a href="{{ url('mozorg.contribute.signup') }}" data-position="CTA button click - landing primary" data-label="Get Involved">{{ _('Get Involved') }}</a></p>
<div class="cycle-pager"></div>
</div>
</section>
<section id="landing-mission" class="section landing-mission">
<div class="container">
<div class="mission-content">
<h2>{{ _('Volunteering with Mozilla&hellip;') }}</h2>
<p>
{# L10n: This paragraph follows the headline, "Volunteering with Mozilla...", so the first sentence continues from that fragment. #}
{% trans %}
is about more than lending a hand. Its about learning, collaborating
and sharing your skills with a global community of Mozillians — coders,
organizers, activists and more — who help shape the Web every day.
{% endtrans %}
</p>
<p class="mission-cta">
<a class="video-play" href="//videos.cdn.mozilla.net/uploads/mozillaorg/Mozilla_2014_i_am.webm" data-element-id="video-iamamozillian" data-linktype="Video text link">
{{ _('See our community in action') }}
</a>
</p>
</div>
<div class="mission-video">
<a class="video-play" href="//videos.cdn.mozilla.net/uploads/mozillaorg/Mozilla_2014_i_am.webm" data-element-id="video-iamamozillian" data-linktype="Video play button">
<img src="{{ media('img/contribute/video-image.png') }}" alt="">
</a>
<div id="video-iamamozillian" class="video">
{{ video('Mozilla_2014_i_am.webm',
'Mozilla_2014_i_am.ogv',
'Mozilla_2014_i_am.mp4',
prefix='//videos.cdn.mozilla.net/uploads/mozillaorg/',
poster=media('img/mozorg/about/poster-i-am.jpg')) }}
</div>
</div>
</div>
</section>
<section id="landing-stories" class="section landing-stories">
<div class="container">
<h2 class="section-title">{{ _('How Mozillians help every day') }}</h2>
<ul class="stories">
<li class="person hcard">
<h3 class="fn given-name">Rubén</h3>
<p class="meta">{{ _('Spain &middot; Activism') }}</p>
<a href="{{ url('mozorg.contribute.story-ruben') }}" class="url">{{ _('Read his story') }} <img src="{{ media('img/contribute/person-ruben.jpg') }}" alt=""></a>
</li>
<li class="person hcard">
<h3 class="fn given-name">Faye</h3>
<p class="meta">{{ _('Philippines &middot; Activism') }}</p>
<a href="{{ url('mozorg.contribute.story-faye') }}" class="url">{{ _('Read her story') }} <img src="{{ media('img/contribute/person-faye.jpg') }}" alt=""></a>
</li>
<li class="person hcard">
<h3 class="fn given-name">Michael</h3>
<p class="meta">{{ _('Switzerland &middot; Coding') }}</p>
<a href="{{ url('mozorg.contribute.story-michael') }}" class="url">{{ _('Read his story') }} <img src="{{ media('img/contribute/person-michael.jpg') }}" alt=""></a>
</li>
</ul>
</div>
</section>
<section id="landing-howto" class="section landing-howto">
<div class="container">
<h2 class="section-title">{{ _('Want to get involved? Heres how.') }}</h2>
<ol class="steps">
<li class="step1">{{ _('Choose what interests you and tell us how youd like to help') }}</li>
<li class="step2">{{ _('Stand by for an email that will connect you to the Mozilla community') }}</li>
<li class="step3">{{ _('Create your Mozillians account and share your contributions with the world') }}</li>
</ol>
<p class="cta"><a href="{{ url('mozorg.contribute.signup') }}" data-position="CTA button click - landing bottom" data-label="Get started">{{ _('Get started') }}</a></p>
</div>
</section>
<section id="landing-notready" class="section landing-notready">
<div class="container">
<h2 class="section-title">{{ _('Not ready to dive in just yet?') }}</h2>
<p class="section-tagline">{{ _('Here are a few other ways you can support Mozilla right now.') }}</p>
<ul class="other-actions">
<li>
<a href="https://sendto.mozilla.org/page/contribute/Give-Now?source=mozillaorg&amp;ref=volunteer_getinvolvedpage201410&amp;utm_campaign=volunteer_getinvolvedpage201410&amp;utm_source=mozillaorg&amp;utm_medium=referral" class="other-donate" data-label="Donate to Mozilla">{{ _('Donate to Mozilla') }}</a>
</li>
<li>
<a href="{{ url('firefox') }}" class="other-download" data-label="Download Firefox">{{ _('Download Firefox') }}</a>
</li>
{# Hide this link for now
<li>
<a href="{{ url('mozorg.about.manifesto') }}" class="other-read" data-label="Read our Manifesto">{{ _('Read our Manifesto') }}</a>
</li>
#}
{# Hide this link for now
<li>
<a href="https://gear.mozilla.org" class="other-shop" data-label="Buy a Mozilla t-shirt">{{ _('Buy a Mozilla t-shirt') }}</a>
</li>
#}
<li>
<a href="https://www.facebook.com/mozilla" class="other-facebook" data-label="Like us on Facebook">{{ _('Like us on Facebook') }}</a>
</li>
<li>
<a href="https://twitter.com/mozilla" class="other-twitter" data-label="Follow us on Twitter">{{ _('Follow us on Twitter') }}</a>
</li>
</ul>
</div>
</section>
{% endblock contrib_content %}

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

@ -2,10 +2,152 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/. -#}
{% add_lang_files "mozorg/contribute" %}
{% extends "mozorg/contribute/contribute-base.html" %}
{% block page_title %}
{{ _('Volunteer Opportunities at Mozilla') }}
{% endblock %}
{% block js %}
{{ js('contribute-2015-landing') }}
{{ js('contribute-2015') }}
{% endblock %}
{% block body_id %}landing{% endblock %}
{% block contrib_nav_cta %}{% endblock %}
{% block contrib_page_title %}{{ _('Volunteer with Mozilla!') }}{% endblock %}
{% block contrib_content %}
<section id="landing-intro" class="section landing-intro">
<div id="slideshow" class="cycle-slideshow" data-cycle-speed="1000" data-cycle-timeout="6000" data-cycle-slides="> .slide" data-cycle-fx="fade" data-cycle-pause-on-hover="false" data-cycle-log="false">
<div class="slide slide-one">
<div class="container">
<p class="section-title">{{ _('Join a global community of game-changers.') }}</p>
</div>
</div>
<div class="slide slide-two">
<div class="container">
{# L10n: this br is for formatting, omit or reposition as needed #}
<p class="section-title">{{ _('Volunteer as much as you like. Or as little.<br> Its totally up to you.') }}</p>
</div>
</div>
<div class="slide slide-three">
<div class="container">
{# L10n: this br is for formatting, omit or reposition as needed #}
<p class="section-title">{{ _('Share your skills and pick up<br> a few new ones along the way.') }}</p>
</div>
</div>
<p class="cta"><a href="{{ url('mozorg.contribute.signup') }}" data-position="CTA button click - landing primary" data-label="Get Involved">{{ _('Get Involved') }}</a></p>
<div class="cycle-pager"></div>
</div>
</section>
<section id="landing-mission" class="section landing-mission">
<div class="container">
<div class="mission-content">
<h2>{{ _('Volunteering with Mozilla&hellip;') }}</h2>
<p>
{# L10n: This paragraph follows the headline, "Volunteering with Mozilla...", so the first sentence continues from that fragment. #}
{% trans %}
is about more than lending a hand. Its about learning, collaborating
and sharing your skills with a global community of Mozillians — coders,
organizers, activists and more — who help shape the Web every day.
{% endtrans %}
</p>
<p class="mission-cta">
<a class="video-play" href="//videos.cdn.mozilla.net/uploads/mozillaorg/Mozilla_2014_i_am.webm" data-element-id="video-iamamozillian" data-linktype="Video text link">
{{ _('See our community in action') }}
</a>
</p>
</div>
<div class="mission-video">
<a class="video-play" href="//videos.cdn.mozilla.net/uploads/mozillaorg/Mozilla_2014_i_am.webm" data-element-id="video-iamamozillian" data-linktype="Video play button">
<img src="{{ media('img/contribute/video-image.png') }}" alt="">
</a>
<div id="video-iamamozillian" class="video">
{{ video('Mozilla_2014_i_am.webm',
'Mozilla_2014_i_am.ogv',
'Mozilla_2014_i_am.mp4',
prefix='//videos.cdn.mozilla.net/uploads/mozillaorg/',
poster=media('img/mozorg/about/poster-i-am.jpg')) }}
</div>
</div>
</div>
</section>
<section id="landing-stories" class="section landing-stories">
<div class="container">
<h2 class="section-title">{{ _('How Mozillians help every day') }}</h2>
<ul class="stories">
<li class="person hcard">
<h3 class="fn given-name">Rubén</h3>
<p class="meta">{{ _('Spain &middot; Activism') }}</p>
<a href="{{ url('mozorg.contribute.story-ruben') }}" class="url">{{ _('Read his story') }} <img src="{{ media('img/contribute/person-ruben.jpg') }}" alt=""></a>
</li>
<li class="person hcard">
<h3 class="fn given-name">Faye</h3>
<p class="meta">{{ _('Philippines &middot; Activism') }}</p>
<a href="{{ url('mozorg.contribute.story-faye') }}" class="url">{{ _('Read her story') }} <img src="{{ media('img/contribute/person-faye.jpg') }}" alt=""></a>
</li>
<li class="person hcard">
<h3 class="fn given-name">Michael</h3>
<p class="meta">{{ _('Switzerland &middot; Coding') }}</p>
<a href="{{ url('mozorg.contribute.story-michael') }}" class="url">{{ _('Read his story') }} <img src="{{ media('img/contribute/person-michael.jpg') }}" alt=""></a>
</li>
</ul>
</div>
</section>
<section id="landing-howto" class="section landing-howto">
<div class="container">
<h2 class="section-title">{{ _('Want to get involved? Heres how.') }}</h2>
<ol class="steps">
<li class="step1">{{ _('Choose what interests you and tell us how youd like to help') }}</li>
<li class="step2">{{ _('Stand by for an email that will connect you to the Mozilla community') }}</li>
<li class="step3">{{ _('Create your Mozillians account and share your contributions with the world') }}</li>
</ol>
<p class="cta"><a href="{{ url('mozorg.contribute.signup') }}" data-position="CTA button click - landing bottom" data-label="Get started">{{ _('Get started') }}</a></p>
</div>
</section>
<section id="landing-notready" class="section landing-notready">
<div class="container">
<h2 class="section-title">{{ _('Not ready to dive in just yet?') }}</h2>
<p class="section-tagline">{{ _('Here are a few other ways you can support Mozilla right now.') }}</p>
<ul class="other-actions">
<li>
<a href="https://sendto.mozilla.org/page/contribute/Give-Now?source=mozillaorg&amp;ref=volunteer_getinvolvedpage201410&amp;utm_campaign=volunteer_getinvolvedpage201410&amp;utm_source=mozillaorg&amp;utm_medium=referral" class="other-donate" data-label="Donate to Mozilla">{{ _('Donate to Mozilla') }}</a>
</li>
<li>
<a href="{{ url('firefox') }}" class="other-download" data-label="Download Firefox">{{ _('Download Firefox') }}</a>
</li>
{# Hide this link for now
<li>
<a href="{{ url('mozorg.about.manifesto') }}" class="other-read" data-label="Read our Manifesto">{{ _('Read our Manifesto') }}</a>
</li>
#}
{# Hide this link for now
<li>
<a href="https://gear.mozilla.org" class="other-shop" data-label="Buy a Mozilla t-shirt">{{ _('Buy a Mozilla t-shirt') }}</a>
</li>
#}
<li>
<a href="https://www.facebook.com/mozilla" class="other-facebook" data-label="Like us on Facebook">{{ _('Like us on Facebook') }}</a>
</li>
<li>
<a href="https://twitter.com/mozilla" class="other-twitter" data-label="Follow us on Twitter">{{ _('Follow us on Twitter') }}</a>
</li>
</ul>
</div>
</section>
{% endblock contrib_content %}
{% if l10n_has_tag('contribute_2015') %}
{% include 'mozorg/contribute/contribute.html' %}
{% else %}
{% include 'mozorg/contribute/contribute-old.html' %}
{% endif %}

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

@ -23,6 +23,9 @@
{% block contrib_content %}
<section class="section inquiry">
<div class="container">
{% if is_old_form %}
{% include "mozorg/contribute/contribute-form.html" %}
{% else %}
<form class="inquiry-form" id="inquiry-form" method="post" action="{{ url('mozorg.contribute.signup') }}">
{% if form.errors %}
{{ form.non_field_errors()|safe }}
@ -205,6 +208,7 @@
<p>{{ _('Not sure how you want to help? No problem. We can find the appropriate contribution activity for you.') }}</p>
</div>
</aside>
{% endif %}
</div>
</section>

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

@ -121,3 +121,14 @@ class TestPageUtil(TestCase):
url.callback(self.rf.get('/'))
ok_(not djrender_mock.called)
l10n_mock.render.assert_called_with(ANY, 'index.html', {'urlname': 'index'})
def test_url_name_set_from_template(self, l10n_mock, djrender_mock):
"""If not provided the URL pattern name should be set from the template path."""
url = page('lebowski/urban_achievers', 'lebowski/achievers.html')
eq_(url.name, 'lebowski.achievers')
def test_url_name_set_from_param(self, l10n_mock, djrender_mock):
"""If provided the URL pattern name should be set from the parameter."""
url = page('lebowski/urban_achievers', 'lebowski/achievers.html',
url_name='proud.we.are.of.all.of.them')
eq_(url.name, 'proud.we.are.of.all.of.them')

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

@ -112,6 +112,39 @@ class TestContributeSignup(TestCase):
self.assertFalse(basket_mock.called)
class TestContributeSignupSwitcher(TestCase):
def setUp(self):
self.rf = RequestFactory()
patcher = patch('bedrock.mozorg.views.lang_file_has_tag')
self.lang_file_has_tag = patcher.start()
self.addCleanup(patcher.stop)
patcher = patch('bedrock.mozorg.views.ContributeSignup')
self.ContributeSignup = patcher.start()
self.addCleanup(patcher.stop)
patcher = patch('bedrock.mozorg.views.ContributeSignupOldForm')
self.ContributeSignupOldForm = patcher.start()
self.addCleanup(patcher.stop)
def test_uses_new_view(self):
"""Uses new view when lang file has the tag."""
req = self.rf.get('/')
self.lang_file_has_tag.return_value = True
views.contribute_signup(req)
self.ContributeSignup.as_view.return_value.assert_called_with(req)
self.assertFalse(self.ContributeSignupOldForm.as_view.return_value.called)
def test_uses_old_view(self):
"""Uses old view when lang file does not have the tag."""
req = self.rf.get('/')
self.lang_file_has_tag.return_value = False
views.contribute_signup(req)
self.ContributeSignupOldForm.as_view.return_value.assert_called_with(req)
self.assertFalse(self.ContributeSignup.as_view.return_value.called)
@patch('bedrock.mozorg.views.l10n_utils.render')
class TestHome(TestCase):
def setUp(self):
@ -243,8 +276,8 @@ class TestContributeStudentAmbassadorsLanding(TestCase):
mock_render.assert_called_with(ANY, ANY, {'tweets': good_val})
@patch.object(l10n_utils.dotlang, 'lang_file_is_active', lambda *x: True)
class TestContribute(TestCase):
@patch.object(views, 'lang_file_is_active', lambda *x: False)
class TestContributeOldPage(TestCase):
def setUp(self):
with self.activate('en-US'):
self.url_en = reverse('mozorg.contribute')
@ -399,6 +432,175 @@ class TestContribute(TestCase):
self.assertIn(EXPECTED, m.body)
@patch.object(l10n_utils.dotlang, 'lang_file_is_active', lambda *x: True)
@patch.object(views, 'lang_file_has_tag', lambda *x: False)
class TestContribute(TestCase):
def setUp(self):
with self.activate('en-US'):
self.url_en = reverse('mozorg.contribute.signup')
with self.activate('pt-BR'):
self.url_pt_br = reverse('mozorg.contribute.signup')
self.contact = 'foo@bar.com'
self.data = {
'contribute-form': 'Y',
'email': self.contact,
'interest': 'coding',
'privacy': True,
'comments': 'Wesh!',
}
def tearDown(self):
mail.outbox = []
@patch.object(ReCaptchaField, 'clean', Mock())
def test_with_autoresponse(self):
"""Test contacts for functional area with autoresponses"""
self.data.update(interest='support')
self.client.post(self.url_en, self.data)
eq_(len(mail.outbox), 2)
cc = ['mana@mozilla.com']
m = mail.outbox[0]
eq_(m.from_email, 'contribute@mozilla.org')
eq_(m.to, ['contribute@mozilla.org'])
eq_(m.cc, cc)
eq_(m.extra_headers['Reply-To'], self.contact)
m = mail.outbox[1]
eq_(m.from_email, 'contribute@mozilla.org')
eq_(m.to, [self.contact])
eq_(m.cc, [])
eq_(m.extra_headers['Reply-To'], ','.join(['contribute@mozilla.org'] +
cc))
@patch.object(ReCaptchaField, 'clean', Mock())
@patch('bedrock.mozorg.email_contribute.basket.subscribe')
@patch('bedrock.mozorg.email_contribute.requests.post')
def test_webmaker_mentor_signup(self, mock_post, mock_subscribe):
"""Test Webmaker Mentor signup form for education functional area"""
self.data.update(interest='education', newsletter=True)
self.client.post(self.url_en, self.data)
assert_false(mock_subscribe.called)
payload = {'email': self.contact, 'custom-1788': '1'}
mock_post.assert_called_with('https://sendto.mozilla.org/page/s/mentor-signup',
data=payload, timeout=2)
@patch.object(ReCaptchaField, 'clean', Mock())
@patch('bedrock.mozorg.email_contribute.basket.subscribe')
@patch('bedrock.mozorg.email_contribute.requests.post')
def test_webmaker_mentor_signup_newsletter_fail(self, mock_post, mock_subscribe):
"""Test Webmaker Mentor signup form when newsletter is not selected"""
self.data.update(interest='education', newsletter=False)
self.client.post(self.url_en, self.data)
assert_false(mock_subscribe.called)
assert_false(mock_post.called)
@patch.object(ReCaptchaField, 'clean', Mock())
@patch('bedrock.mozorg.email_contribute.basket.subscribe')
@patch('bedrock.mozorg.email_contribute.requests.post')
def test_webmaker_mentor_signup_functional_area_fail(self, mock_post, mock_subscribe):
"""Test Webmaker Mentor signup form when functional area is not education"""
self.data.update(interest='coding', newsletter=True)
self.client.post(self.url_en, self.data)
mock_subscribe.assert_called_with(self.contact, 'about-mozilla', source_url=ANY)
assert_false(mock_post.called)
@patch.object(ReCaptchaField, 'clean', Mock())
@patch('bedrock.mozorg.email_contribute.basket.subscribe')
@patch('bedrock.mozorg.email_contribute.requests.post')
def test_webmaker_mentor_signup_timeout_fail(self, mock_post, mock_subscribe):
"""Test Webmaker Mentor signup form when request times out"""
mock_post.side_effect = Timeout('Timeout')
self.data.update(interest='education', newsletter=True)
res = self.client.post(self.url_en, self.data)
assert_false(mock_subscribe.called)
eq_(res.status_code, 302) # redirect to thankyou page
@patch.object(ReCaptchaField, 'clean', Mock())
@patch('bedrock.mozorg.email_contribute.jingo.render_to_string')
def test_no_autoresponse_locale(self, render_mock):
"""
L10N version to test contacts for functional area without autoresponses
"""
# first value is for send() and 2nd is for autorespond()
render_mock.side_effect = ['The Dude minds, man!',
TemplateNotFound('coding.txt')]
self.data.update(interest='coding')
self.client.post(self.url_pt_br, self.data)
eq_(len(mail.outbox), 1)
m = mail.outbox[0]
eq_(m.from_email, 'contribute@mozilla.org')
eq_(m.to, ['contribute@mozilla.org'])
eq_(m.cc, ['envolva-se-mozilla-brasil@googlegroups.com'])
eq_(m.extra_headers['Reply-To'], self.contact)
@patch.object(ReCaptchaField, 'clean', Mock())
@patch('bedrock.mozorg.email_contribute.jingo.render_to_string')
def test_with_autoresponse_locale(self, render_mock):
"""
L10N version to test contacts for functional area with autoresponses
"""
render_mock.side_effect = 'The Dude abides.'
self.data.update(interest='support')
self.client.post(self.url_pt_br, self.data)
eq_(len(mail.outbox), 2)
cc = ['envolva-se-mozilla-brasil@googlegroups.com']
m = mail.outbox[0]
eq_(m.from_email, 'contribute@mozilla.org')
eq_(m.to, ['contribute@mozilla.org'])
eq_(m.cc, cc)
eq_(m.extra_headers['Reply-To'], self.contact)
m = mail.outbox[1]
eq_(m.from_email, 'contribute@mozilla.org')
eq_(m.to, [self.contact])
eq_(m.cc, [])
eq_(m.extra_headers['Reply-To'], ','.join(['contribute@mozilla.org'] +
cc))
@patch.object(ReCaptchaField, 'clean', Mock())
def test_honeypot(self):
"""
If honeypot is triggered no email should go out but page should proceed normally.
"""
self.data.update(interest='support')
self.data.update(office_fax='Yes')
resp = self.client.post(self.url_en, self.data)
eq_(len(mail.outbox), 0)
eq_(resp.status_code, 302)
ok_(resp['location'].endswith('/thankyou/'))
@patch.object(ReCaptchaField, 'clean', Mock())
def test_emails_not_escaped(self):
"""
Strings in the contribute form should not be HTML escaped
when inserted into the email, which is just text.
E.g. if they entered
J'adore le ''Renard de feu''
the email should not contain
J&#39;adore le &#39;&#39;Renard de feu&#39;&#39;
Tags are still stripped, though.
"""
STRING = u"J'adore Citröns & <Piñatas> so there"
EXPECTED = u"J'adore Citröns & so there"
self.data.update(comments=STRING)
self.client.post(self.url_en, self.data)
eq_(len(mail.outbox), 2)
m = mail.outbox[0]
self.assertIn(EXPECTED, m.body)
class TestRobots(TestCase):
@override_settings(SITE_URL='https://www.mozilla.org')
def test_production_disallow_all_is_false(self):

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

@ -175,9 +175,7 @@ urlpatterns = patterns('',
page('contribute/stories/shreyas', 'mozorg/contribute/story-shreyas.html'),
page('contribute/stories/michael', 'mozorg/contribute/story-michael.html'),
url('^contribute/$', views.contribute, name='mozorg.contribute',
kwargs={'template': 'mozorg/contribute/index.html',
'return_to_form': False}),
url('^contribute/$', views.contribute_index, name='mozorg.contribute'),
url('^contribute/event/$', views.contribute,
kwargs={'template': 'mozorg/contribute/index.html',
'return_to_form': True},
@ -190,8 +188,7 @@ urlpatterns = patterns('',
name='mozorg.contribute_embed',
kwargs={'template': 'mozorg/contribute/contribute-embed.html',
'return_to_form': False}),
url('^contribute/signup/$', views.ContributeSignup.as_view(),
name='mozorg.contribute.signup'),
url('^contribute/signup/$', views.contribute_signup, name='mozorg.contribute.signup'),
url('^contribute/thankyou/$',
views.ContributeSignupThankyou.as_view(),
name='mozorg.contribute.thankyou'),

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

@ -32,13 +32,14 @@ class HttpResponseJSON(HttpResponse):
status=status)
def page(name, tmpl, decorators=None, **kwargs):
def page(name, tmpl, decorators=None, url_name=None, **kwargs):
"""
Define a bedrock page.
The URL name is the template name, with the extension stripped and the
slashes changed to dots. So if tmpl="path/to/template.html", then the
page's URL name will be "path.to.template".
page's URL name will be "path.to.template". Set the `url_name` parameter
to override this name.
@param name: The URL regex pattern. If not empty, a trailing slash is
added automatically, so it shouldn't be included in the parameter
@ -46,14 +47,17 @@ def page(name, tmpl, decorators=None, **kwargs):
@param tmpl: The template name. Also used to come up with the URL name.
@param decorators: A decorator or an iterable of decorators that should
be applied to the view.
@param url_name: The value to use as the URL name, default is to coerce
the template path into a name as described above.
@param kwargs: Any additional arguments are passed to l10n_utils.render
after the request and the template name.
"""
pattern = r'^%s/$' % name if name else r'^$'
# Set the name of the view to the template path replaced with dots
(base, ext) = os.path.splitext(tmpl)
view_name = base.replace('/', '.')
if url_name is None:
# Set the name of the view to the template path replaced with dots
(base, ext) = os.path.splitext(tmpl)
url_name = base.replace('/', '.')
# we don't have a caching backend yet, so no csrf (it's just a
# newsletter form anyway)
@ -62,8 +66,8 @@ def page(name, tmpl, decorators=None, **kwargs):
if newrelic:
# Name this in New Relic to differentiate pages
newrelic.agent.set_transaction_name(
'mozorg.util.page:' + view_name.replace('.', '_'))
kwargs.setdefault('urlname', view_name)
'mozorg.util.page:' + url_name.replace('.', '_'))
kwargs.setdefault('urlname', url_name)
# skip l10n if path exempt
name_prefix = request.path_info.split('/', 2)[1]
@ -73,7 +77,7 @@ def page(name, tmpl, decorators=None, **kwargs):
return l10n_utils.render(request, tmpl, kwargs)
# This is for graphite so that we can differentiate pages
_view.page_name = view_name
_view.page_name = url_name
# Apply decorators
if decorators:
@ -90,7 +94,7 @@ def page(name, tmpl, decorators=None, **kwargs):
log.exception('decorators not iterable or does not contain '
'callable items')
return url(pattern, _view, name=view_name)
return url(pattern, _view, name=url_name)
def hide_contrib_form(lang):

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

@ -19,7 +19,7 @@ import requests
from lib import l10n_utils
from commonware.decorators import xframe_allow
from funfactory.urlresolvers import reverse
from lib.l10n_utils.dotlang import _, lang_file_is_active
from lib.l10n_utils.dotlang import _, lang_file_is_active, lang_file_has_tag
from bedrock.mozorg import email_contribute
from bedrock.mozorg.credits import CreditsFile
@ -117,6 +117,33 @@ class ContributeSignup(l10n_utils.LangFilesMixin, FormView):
return super(ContributeSignup, self).form_valid(form)
class ContributeSignupOldForm(l10n_utils.LangFilesMixin, FormView):
template_name = 'mozorg/contribute/signup.html'
form_class = ContributeForm
def get_context_data(self, **kwargs):
kwargs['is_old_form'] = True
return super(ContributeSignupOldForm, self).get_context_data(**kwargs)
def form_valid(self, form):
honeypot = form.cleaned_data.get('office_fax')
if not honeypot:
email_contribute.handle_form(self.request, form)
return super(ContributeSignupOldForm, self).form_valid(form)
def get_success_url(self):
return reverse('mozorg.contribute.thankyou')
def contribute_signup(request):
use_new_form = lang_file_has_tag('mozorg/contribute/index',
l10n_utils.get_locale(request),
'2015_signup_form')
view_class = ContributeSignup if use_new_form else ContributeSignupOldForm
return view_class.as_view()(request)
class ContributeSignupThankyou(l10n_utils.LangFilesMixin, TemplateView):
template_name = 'mozorg/contribute/thankyou.html'
category_re = re.compile('^\w{5,20}$')
@ -130,6 +157,10 @@ class ContributeSignupThankyou(l10n_utils.LangFilesMixin, TemplateView):
return cxt
class ContributeIndex(l10n_utils.LangFilesMixin, TemplateView):
template_name = 'mozorg/contribute/index.html'
@csrf_exempt
def contribute(request, template, return_to_form):
newsletter_form = NewsletterFooterForm('about-mozilla', l10n_utils.get_locale(request))
@ -161,6 +192,14 @@ def contribute(request, template, return_to_form):
'hide_form': hide_contrib_form(request.locale)})
def contribute_index(request):
if lang_file_is_active('mozorg/contribute/index',
l10n_utils.get_locale(request)):
return ContributeIndex.as_view()(request)
else:
return contribute(request, 'mozorg/contribute/contribute-old.html', False)
@xframe_allow
@csrf_exempt
def contribute_embed(request, template, return_to_form):

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

@ -74,7 +74,7 @@ def js_escape(string):
def l10n_has_tag(ctx, tag, langfile=None):
"""Return boolean whether the given template's lang files have the given tag."""
if langfile:
return lang_file_has_tag(langfile, tag=tag)
return lang_file_has_tag(langfile, ctx['LANG'], tag)
else:
return template_has_tag(ctx['template'], ctx['LANG'], tag)

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

@ -15,8 +15,8 @@ from l10n_utils import helpers
class TestL10nHasTag(TestCase):
def test_uses_langfile(self, lfht_mock):
"""If langfile param specified should only check that file."""
helpers.l10n_has_tag({'langfile': 'dude'}, 'abide', langfile='uli')
lfht_mock.assert_called_with('uli', tag='abide')
helpers.l10n_has_tag({'langfile': 'dude', 'LANG': 'fr'}, 'abide', langfile='uli')
lfht_mock.assert_called_with('uli', 'fr', 'abide')
@patch.object(helpers, 'template_has_tag')
def test_checks_template_by_default(self, tht_mock, lfht_mock):

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

@ -950,6 +950,13 @@ textarea:focus {
.container {
padding-top: 0;
}
// old inquiry form
.billboard {
border-bottom: none;
margin: 0;
padding: 0;
}
}
.inquiry-form {