зеркало из https://github.com/mozilla/bedrock.git
This commit is contained in:
Родитель
68dee4e33b
Коммит
a31f0e64c7
|
@ -9,6 +9,7 @@
|
|||
{% set android_url = play_store_url('vpn', campaign) %}
|
||||
{% set ios_url = app_store_url('vpn', campaign) %}
|
||||
{% set redirect_url = 'http://www.mozilla.org/products/vpn/mobile/app/?product=vpn&campaign=' + campaign %}
|
||||
{% set local_currency_notice = country_code in ["UG", "SN", "UA", "KE"] and ftl_has_messages('vpn-pricing-transaction-may-be-in') %}
|
||||
|
||||
<section class="mzp-c-split vpn-pricing-mobile-subscription mzp-l-split-center-on-sm-md mzp-t-content-xl">
|
||||
<div class="mzp-c-split-container">
|
||||
|
@ -16,13 +17,50 @@
|
|||
{% if heading %}
|
||||
<h2 class="u-title-lg">{{ heading }}</h2>
|
||||
{% endif %}
|
||||
<p class="vpn-pricing-desktop-instruction u-body-lg">
|
||||
{% if android_sub_only %}
|
||||
{{ ftl('vpn-pricing-scan-qrcode-to-download-android', fallback='vpn-pricing-scan-qrcode-to-download') }}
|
||||
{% else %}
|
||||
{{ ftl('vpn-pricing-scan-qrcode-to-download') }}
|
||||
{% endif %}
|
||||
</p>
|
||||
|
||||
{% if switch('vpn-wave-vii-pricing') %}
|
||||
<div class="c-pricing-block-mobile-wrapper">
|
||||
<div class="c-pricing-block-mobile">
|
||||
<p class="c-pricing-block-mobile-tag">
|
||||
{{ ftl('vpn-shared-pricing-recommended-offer') }}
|
||||
</p>
|
||||
|
||||
<h2 class="c-pricing-block-mobile-heading">
|
||||
{{ ftl('vpn-pricing-annual') }}
|
||||
</h2>
|
||||
|
||||
<h3 class="c-pricing-block-mobile-sub-heading">
|
||||
{{ vpn_mobile_monthly_price(plan='12-month', country_code=country_code, lang=LANG) }}
|
||||
</h3>
|
||||
|
||||
{% if local_currency_notice %}
|
||||
<p class="c-pricing-block-mobile-currency-info">
|
||||
{{ ftl('vpn-pricing-transaction-may-be-in') }}
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
<p class="c-pricing-block-mobile-total">
|
||||
{{ vpn_mobile_total_price(country_code=country_code, lang=LANG) }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="c-pricing-block-mobile">
|
||||
<h2 class="c-pricing-block-mobile-heading">
|
||||
{{ ftl('vpn-pricing-monthly') }}
|
||||
</h2>
|
||||
|
||||
<h3 class="c-pricing-block-mobile-sub-heading">
|
||||
{{ vpn_mobile_monthly_price(plan='monthly', country_code=country_code, lang=LANG) }}
|
||||
</h3>
|
||||
|
||||
{% if local_currency_notice %}
|
||||
<p class="c-pricing-block-mobile-currency-info">
|
||||
{{ ftl('vpn-pricing-transaction-may-be-in') }}
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<ol class="vpn-pricing-mobile-steps u-body-lg">
|
||||
{% if android_sub_only %}
|
||||
|
@ -34,6 +72,14 @@
|
|||
<li><span>{{ ftl('vpn-pricing-access', servers=connect_servers, countries=connect_countries) }}</span></li>
|
||||
</ol>
|
||||
|
||||
<p class="vpn-pricing-desktop-instruction u-body-lg">
|
||||
{% if android_sub_only %}
|
||||
{{ ftl('vpn-pricing-scan-qrcode-to-download-android', fallback='vpn-pricing-scan-qrcode-to-download') }}
|
||||
{% else %}
|
||||
{{ ftl('vpn-pricing-scan-qrcode-to-download') }}
|
||||
{% endif %}
|
||||
</p>
|
||||
|
||||
{{ picture(
|
||||
url='img/products/vpn/landing-refresh/devices.svg',
|
||||
sources=[
|
||||
|
|
|
@ -74,6 +74,15 @@ def _vpn_get_available_plans(country_code, lang):
|
|||
return country_plans.get(lang, country_plans.get("default"))
|
||||
|
||||
|
||||
def _vpn_get_mobile_plans(country_code):
|
||||
"""
|
||||
Get mobile only subscription plans using country_code.
|
||||
Defaults to "US" if no matching country code is found.
|
||||
"""
|
||||
|
||||
return settings.VPN_MOBILE_SUB_PRICING.get(country_code, settings.VPN_MOBILE_SUB_PRICING["US"])
|
||||
|
||||
|
||||
def _vpn_product_link(product_url, entrypoint, link_text, class_name=None, optional_parameters=None, optional_attributes=None):
|
||||
separator = "&" if "?" in product_url else "?"
|
||||
client_id = settings.VPN_CLIENT_ID
|
||||
|
@ -194,6 +203,37 @@ def vpn_monthly_price(ctx, plan=VPN_12_MONTH_PLAN, country_code=None, lang=None)
|
|||
return Markup(markup)
|
||||
|
||||
|
||||
@library.global_function
|
||||
@jinja2.pass_context
|
||||
def vpn_mobile_monthly_price(ctx, plan=VPN_12_MONTH_PLAN, country_code=None, lang=None):
|
||||
"""
|
||||
Render a localized string displaying VPN monthly plan price for a mobile subscription.
|
||||
This is used for countries where a VPN subscription can only be purchased through the
|
||||
Google Play Store or the Apple App Store, and uses a different pricing plan matrix to
|
||||
countries that purchase through FxA / sub-plat.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
In Template
|
||||
-----------
|
||||
|
||||
{{ vpn_mobile_monthly_price(country_code=country_code, lang=LANG) }}
|
||||
"""
|
||||
|
||||
available_plans = _vpn_get_mobile_plans(country_code)
|
||||
selected_plan = available_plans.get(plan, VPN_12_MONTH_PLAN)
|
||||
price = selected_plan.get("price")
|
||||
currency = selected_plan.get("currency")
|
||||
currency_locale = lang.replace("-", "_")
|
||||
amount = _format_currency(price, currency, currency_locale)
|
||||
price = ftl("vpn-shared-pricing-monthly", amount=amount, ftl_files=FTL_FILES)
|
||||
|
||||
markup = f'<span class="vpn-monthly-price-display">{price}</span>'
|
||||
|
||||
return Markup(markup)
|
||||
|
||||
|
||||
@library.global_function
|
||||
@jinja2.pass_context
|
||||
def vpn_total_price(ctx, country_code=None, lang=None):
|
||||
|
@ -226,6 +266,37 @@ def vpn_total_price(ctx, country_code=None, lang=None):
|
|||
return Markup(markup)
|
||||
|
||||
|
||||
@library.global_function
|
||||
@jinja2.pass_context
|
||||
def vpn_mobile_total_price(ctx, country_code=None, lang=None):
|
||||
"""
|
||||
Render a localized string displaying VPN total plan price for a mobile subscription.
|
||||
This is used for countries where a VPN subscription can only be purchased through the
|
||||
Google Play Store or the Apple App Store, and uses a different pricing plan matrix to
|
||||
countries that purchase through FxA / sub-plat.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
In Template
|
||||
-----------
|
||||
|
||||
{{ vpn_mobile_total_price(country_code=country_code, lang=LANG) }}
|
||||
"""
|
||||
|
||||
available_plans = _vpn_get_mobile_plans(country_code)
|
||||
selected_plan = available_plans.get(VPN_12_MONTH_PLAN)
|
||||
price = selected_plan.get("total")
|
||||
currency = selected_plan.get("currency")
|
||||
currency_locale = lang.replace("-", "_")
|
||||
amount = _format_currency(price, currency, currency_locale)
|
||||
price = ftl("vpn-shared-pricing-total", amount=amount, ftl_files=FTL_FILES)
|
||||
|
||||
markup = price
|
||||
|
||||
return Markup(markup)
|
||||
|
||||
|
||||
@library.global_function
|
||||
@jinja2.pass_context
|
||||
def vpn_saving(ctx, country_code=None, lang=None, ftl_string="vpn-shared-pricing-save-percent"):
|
||||
|
|
|
@ -1231,7 +1231,7 @@ class TestVPNMonthlyPrice(TestCase):
|
|||
|
||||
def _render(self, plan, country_code, lang):
|
||||
req = self.rf.get("/")
|
||||
req.locale = "en-US"
|
||||
req.locale = lang
|
||||
return render(f"{{{{ vpn_monthly_price('{plan}', '{country_code}', '{lang}') }}}}", {"request": req})
|
||||
|
||||
def test_vpn_monthly_price_usd_en_us(self):
|
||||
|
@ -1385,6 +1385,315 @@ class TestVPNMonthlyPrice(TestCase):
|
|||
self.assertEqual(markup, expected)
|
||||
|
||||
|
||||
class TestVPNMobileMonthlyPrice(TestCase):
|
||||
rf = RequestFactory()
|
||||
|
||||
def _render(self, plan, country_code, lang):
|
||||
req = self.rf.get("/")
|
||||
req.locale = "en-US"
|
||||
return render(f"{{{{ vpn_mobile_monthly_price('{plan}', '{country_code}', '{lang}') }}}}", {"request": req})
|
||||
|
||||
def test_vpn_monthly_price_au_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="AU", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">A$14.99<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_au_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="AU", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">A$7.50<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_bd_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="BD", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">BDT1,200.00<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_bd_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="BD", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">BDT583.33<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_br_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="BR", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">R$56.00<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_br_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="BR", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">R$27.50<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_cl_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="CL", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">CLP9,300<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_cl_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="CL", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">CLP4,582<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_co_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="CO", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">COP41,900.00<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_co_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="CO", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">COP20,825.00<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_eg_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="EG", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">EGP479.99<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_eg_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="EG", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">EGP241.67<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_gr_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="GR", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">€9.99<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_gr_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="GR", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">€4.99<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_id_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="ID", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">IDR155,000.00<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_id_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="ID", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">IDR75,000.00<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_in_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="IN", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">₹839.00<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_in_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="IN", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">₹416.58<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_ke_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="KE", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">$9.99<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_ke_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="KE", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">$5.00<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_kr_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="KR", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">₩13,500<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_kr_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="KR", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">₩6,658<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_ma_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="MA", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">MAD99.00<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_ma_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="MA", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">MAD50.00<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_mx_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="MX", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">MX$189.00<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_mx_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="MX", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">MX$95.75<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_ng_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="NG", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">NGN15,900.00<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_ng_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="NG", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">NGN8,325.00<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_no_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="NO", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">NOK110.00<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_no_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="NO", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">NOK54.17<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_sa_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="SA", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">SAR36.99<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_sa_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="SA", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">SAR18.75<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_sn_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="SN", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">$9.99<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_sn_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="SN", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">$4.99<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_th_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="TH", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">THB330.00<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_th_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="TH", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">THB165.83<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_tr_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="TR", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">TRY339.99<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_tr_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="TR", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">TRY166.67<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_tw_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="TW", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">NT$320.00<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_tw_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="TW", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">NT$158.33<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_ua_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="UA", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">$9.99<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_ua_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="UA", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">$5.00<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_ug_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="UG", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">$9.99<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_ug_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="UG", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">$4.99<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_vn_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="VN", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">₫249,000<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_vn_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="VN", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">₫124,917<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_za_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="ZA", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">ZAR169.99<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_za_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="ZA", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">ZAR83.33<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_monthly_price_unknown_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="monthly", country_code="", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">$9.99<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_price_unknown_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(plan="12-month", country_code="", lang="en-US")
|
||||
expected = '<span class="vpn-monthly-price-display">$4.99<span>/month</span></span>'
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
|
||||
@override_settings(
|
||||
VPN_VARIABLE_PRICING=TEST_VPN_VARIABLE_PRICING,
|
||||
)
|
||||
|
@ -1393,7 +1702,7 @@ class TestVPNTotalPrice(TestCase):
|
|||
|
||||
def _render(self, country_code, lang):
|
||||
req = self.rf.get("/")
|
||||
req.locale = "en-US"
|
||||
req.locale = lang
|
||||
return render(f"{{{{ vpn_total_price('{country_code}', '{lang}') }}}}", {"request": req})
|
||||
|
||||
def test_vpn_12_month_total_price_usd_en_us(self):
|
||||
|
@ -1481,6 +1790,165 @@ class TestVPNTotalPrice(TestCase):
|
|||
self.assertEqual(markup, expected)
|
||||
|
||||
|
||||
class TestVPNMobileTotalPrice(TestCase):
|
||||
rf = RequestFactory()
|
||||
|
||||
def _render(self, country_code, lang):
|
||||
req = self.rf.get("/")
|
||||
req.locale = lang
|
||||
return render(f"{{{{ vpn_mobile_total_price('{country_code}', '{lang}') }}}}", {"request": req})
|
||||
|
||||
def test_vpn_12_month_total_price_au_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="AU", lang="en-US")
|
||||
expected = "A$89.99 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_bd_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="BD", lang="en-US")
|
||||
expected = "BDT7,000.00 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_br_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="BR", lang="en-US")
|
||||
expected = "R$330.00 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_cl_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="CL", lang="en-US")
|
||||
expected = "CLP54,990 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_co_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="CO", lang="en-US")
|
||||
expected = "COP249,900.00 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_eg_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="EG", lang="en-US")
|
||||
expected = "EGP2,899.99 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_gr_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="GR", lang="en-US")
|
||||
expected = "€59.88 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_id_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="ID", lang="en-US")
|
||||
expected = "IDR900,000.00 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_in_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="IN", lang="en-US")
|
||||
expected = "₹4,999.00 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_ke_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="KE", lang="en-US")
|
||||
expected = "$59.99 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_kr_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="KR", lang="en-US")
|
||||
expected = "₩79,900 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_ma_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="MA", lang="en-US")
|
||||
expected = "MAD600.00 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_mx_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="MX", lang="en-US")
|
||||
expected = "MX$1,149.00 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_ng_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="NG", lang="en-US")
|
||||
expected = "NGN99,900.00 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_no_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="NO", lang="en-US")
|
||||
expected = "NOK650.00 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_sa_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="SA", lang="en-US")
|
||||
expected = "SAR224.99 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_sn_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="SN", lang="en-US")
|
||||
expected = "$59.88 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_th_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="TH", lang="en-US")
|
||||
expected = "THB1,990.00 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_tr_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="TR", lang="en-US")
|
||||
expected = "TRY1,999.99 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_tw_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="TW", lang="en-US")
|
||||
expected = "NT$1,900.00 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_ua_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="UA", lang="en-US")
|
||||
expected = "$59.99 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_ug_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="UG", lang="en-US")
|
||||
expected = "$59.88 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_vn_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="VN", lang="en-US")
|
||||
expected = "₫1,499,000 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_za_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="ZA", lang="en-US")
|
||||
expected = "ZAR999.99 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
def test_vpn_12_month_total_price_unknown_en_us(self):
|
||||
"""Should return expected markup"""
|
||||
markup = self._render(country_code="", lang="en-US")
|
||||
expected = "$59.88 total"
|
||||
self.assertEqual(markup, expected)
|
||||
|
||||
|
||||
@override_settings(
|
||||
VPN_VARIABLE_PRICING=TEST_VPN_VARIABLE_PRICING,
|
||||
)
|
||||
|
@ -1489,7 +1957,7 @@ class TestVPNSaving(TestCase):
|
|||
|
||||
def _render(self, country_code, lang):
|
||||
req = self.rf.get("/")
|
||||
req.locale = "en-US"
|
||||
req.locale = lang
|
||||
return render(f"{{{{ vpn_saving('{country_code}', '{lang}') }}}}", {"request": req})
|
||||
|
||||
def test_vpn_12_month_saving_usd(self):
|
||||
|
|
|
@ -1736,6 +1736,286 @@ VPN_VARIABLE_PRICING = {
|
|||
},
|
||||
}
|
||||
|
||||
# Simplified pricing matrix for countries that can
|
||||
# only purchase a subscription through the app store.
|
||||
VPN_MOBILE_SUB_PRICING = {
|
||||
"AU": { # Australia
|
||||
"12-month": {
|
||||
"price": "7.5",
|
||||
"total": "89.99",
|
||||
"currency": "AUD",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "14.99",
|
||||
"currency": "AUD",
|
||||
},
|
||||
},
|
||||
"BD": { # Bangladesh
|
||||
"12-month": {
|
||||
"price": "583.33",
|
||||
"total": "7000",
|
||||
"currency": "BDT",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "1200",
|
||||
"currency": "BDT",
|
||||
},
|
||||
},
|
||||
"BR": { # Brazil
|
||||
"12-month": {
|
||||
"price": "27.50",
|
||||
"total": "330",
|
||||
"currency": "BRL",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "56",
|
||||
"currency": "BRL",
|
||||
},
|
||||
},
|
||||
"CL": { # Chile
|
||||
"12-month": {
|
||||
"price": "4582.50",
|
||||
"total": "54990",
|
||||
"currency": "CLP",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "9300",
|
||||
"currency": "CLP",
|
||||
},
|
||||
},
|
||||
"CO": { # Colombia
|
||||
"12-month": {
|
||||
"price": "20825",
|
||||
"total": "249900",
|
||||
"currency": "COP",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "41900",
|
||||
"currency": "COP",
|
||||
},
|
||||
},
|
||||
"EG": { # Egypt
|
||||
"12-month": {
|
||||
"price": "241.67",
|
||||
"total": "2899.99",
|
||||
"currency": "EGP",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "479.99",
|
||||
"currency": "EGP",
|
||||
},
|
||||
},
|
||||
"GR": { # Greece
|
||||
"12-month": {
|
||||
"price": "4.99",
|
||||
"total": "59.88",
|
||||
"currency": "EUR",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "9.99",
|
||||
"currency": "EUR",
|
||||
},
|
||||
},
|
||||
"ID": { # Indonesia
|
||||
"12-month": {
|
||||
"price": "75000",
|
||||
"total": "900000",
|
||||
"currency": "IDR",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "155000",
|
||||
"currency": "IDR",
|
||||
},
|
||||
},
|
||||
"IN": { # India
|
||||
"12-month": {
|
||||
"price": "416.58",
|
||||
"total": "4999",
|
||||
"currency": "INR",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "839",
|
||||
"currency": "INR",
|
||||
},
|
||||
},
|
||||
"KE": { # Kenya
|
||||
"12-month": {
|
||||
"price": "5.00",
|
||||
"total": "59.99",
|
||||
"currency": "USD",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "9.99",
|
||||
"currency": "USD",
|
||||
},
|
||||
},
|
||||
"KR": { # South Korea
|
||||
"12-month": {
|
||||
"price": "6658.33",
|
||||
"total": "79900",
|
||||
"currency": "KRW",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "13500",
|
||||
"currency": "KRW",
|
||||
},
|
||||
},
|
||||
"MA": { # Morocco
|
||||
"12-month": {
|
||||
"price": "50",
|
||||
"total": "600",
|
||||
"currency": "MAD",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "99",
|
||||
"currency": "MAD",
|
||||
},
|
||||
},
|
||||
"MX": { # Mexico
|
||||
"12-month": {
|
||||
"price": "95.75",
|
||||
"total": "1149",
|
||||
"currency": "MXN",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "189",
|
||||
"currency": "MXN",
|
||||
},
|
||||
},
|
||||
"NG": { # Nigeria
|
||||
"12-month": {
|
||||
"price": "8325",
|
||||
"total": "99900",
|
||||
"currency": "NGN",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "15900",
|
||||
"currency": "NGN",
|
||||
},
|
||||
},
|
||||
"NO": { # Norway
|
||||
"12-month": {
|
||||
"price": "54.17",
|
||||
"total": "650",
|
||||
"currency": "NOK",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "110",
|
||||
"currency": "NOK",
|
||||
},
|
||||
},
|
||||
"SA": { # Saudi Arabia
|
||||
"12-month": {
|
||||
"price": "18.75",
|
||||
"total": "224.99",
|
||||
"currency": "SAR",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "36.99",
|
||||
"currency": "SAR",
|
||||
},
|
||||
},
|
||||
"SN": { # Senegal
|
||||
"12-month": {
|
||||
"price": "4.99",
|
||||
"total": "59.88",
|
||||
"currency": "USD",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "9.99",
|
||||
"currency": "USD",
|
||||
},
|
||||
},
|
||||
"TH": { # Thailand
|
||||
"12-month": {
|
||||
"price": "165.83",
|
||||
"total": "1990",
|
||||
"currency": "THB",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "330",
|
||||
"currency": "THB",
|
||||
},
|
||||
},
|
||||
"TR": { # Turkey
|
||||
"12-month": {
|
||||
"price": "166.67",
|
||||
"total": "1999.99",
|
||||
"currency": "TRY",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "339.99",
|
||||
"currency": "TRY",
|
||||
},
|
||||
},
|
||||
"TW": { # Taiwan
|
||||
"12-month": {
|
||||
"price": "158.33",
|
||||
"total": "1900",
|
||||
"currency": "TWD",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "320",
|
||||
"currency": "TWD",
|
||||
},
|
||||
},
|
||||
"UA": { # Ukraine
|
||||
"12-month": {
|
||||
"price": "5.00",
|
||||
"total": "59.99",
|
||||
"currency": "USD",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "9.99",
|
||||
"currency": "USD",
|
||||
},
|
||||
},
|
||||
"UG": { # Uganda
|
||||
"12-month": {
|
||||
"price": "4.99",
|
||||
"total": "59.88",
|
||||
"currency": "USD",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "9.99",
|
||||
"currency": "USD",
|
||||
},
|
||||
},
|
||||
"US": { # United States (only used as a fallback should a country match not be found).
|
||||
"12-month": {
|
||||
"price": "4.99",
|
||||
"total": "59.88",
|
||||
"currency": "USD",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "9.99",
|
||||
"currency": "USD",
|
||||
},
|
||||
},
|
||||
"VN": { # Vietnam
|
||||
"12-month": {
|
||||
"price": "124917",
|
||||
"total": "1499000",
|
||||
"currency": "VND",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "249000",
|
||||
"currency": "VND",
|
||||
},
|
||||
},
|
||||
"ZA": { # South Africa
|
||||
"12-month": {
|
||||
"price": "83.33",
|
||||
"total": "999.99",
|
||||
"currency": "ZAR",
|
||||
},
|
||||
"monthly": {
|
||||
"price": "169.99",
|
||||
"currency": "ZAR",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
# Mozilla VPN Geo restrictions
|
||||
# https://github.com/mozilla-services/guardian-website/blob/master/server/constants.ts
|
||||
|
||||
|
|
|
@ -67,3 +67,4 @@ vpn-pricing-scan-qrcode-to-download-android = To download the app, scan the QR C
|
|||
vpn-pricing-sign-up-on-your-mobile-device = Sign up for a { -brand-name-mozilla-vpn } subscription on your mobile device
|
||||
vpn-pricing-sign-up-on-your-android-device = Sign up for a { -brand-name-mozilla-vpn } subscription on your Android device
|
||||
vpn-pricing-download-the-app = Download the app
|
||||
vpn-pricing-transaction-may-be-in = * Transaction may be in local currency equivalent.
|
||||
|
|
|
@ -247,7 +247,7 @@ $image-path: '/media/protocol/img';
|
|||
}
|
||||
|
||||
@media #{$mq-md} {
|
||||
margin: $spacing-2xl 0;
|
||||
margin: $spacing-xl 0 $spacing-2xl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -340,3 +340,76 @@ html.android {
|
|||
padding-top: 0;
|
||||
margin-top: -$spacing-2xl;
|
||||
}
|
||||
|
||||
// Mobile subscription pricing display
|
||||
|
||||
.c-pricing-block-mobile-wrapper {
|
||||
margin-top: $spacing-2xl;
|
||||
|
||||
@media #{$mq-xl} {
|
||||
display: grid;
|
||||
grid-gap: $spacing-lg;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.c-pricing-block-mobile {
|
||||
background: $color-marketing-gray-20;
|
||||
border-radius: $border-radius-md;
|
||||
margin-bottom: $spacing-lg;
|
||||
padding: $spacing-md;
|
||||
position: relative;
|
||||
@include bidi(((text-align, left, right),));
|
||||
}
|
||||
|
||||
.c-pricing-block-mobile-tag {
|
||||
background: $color-vpn-brand-refresh-purple-20;
|
||||
border-radius: $border-radius-md;
|
||||
color: $color-white;
|
||||
display: inline-block;
|
||||
font-weight: bold;
|
||||
padding: $spacing-xs $spacing-md;
|
||||
@include text-body-sm;
|
||||
|
||||
html[lang^='en'] & {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
@media #{$mq-xl} {
|
||||
position: absolute;
|
||||
top: $spacing-md;
|
||||
@include bidi(((left, $spacing-md, right, auto),));
|
||||
}
|
||||
}
|
||||
|
||||
.c-pricing-block-mobile-heading {
|
||||
border-bottom: 2px solid $color-black;
|
||||
padding-bottom: $spacing-md;
|
||||
@include text-title-xs;
|
||||
|
||||
@media #{$mq-xl} {
|
||||
margin-top: $spacing-2xl;
|
||||
}
|
||||
}
|
||||
|
||||
.c-pricing-block-mobile-sub-heading {
|
||||
margin-bottom: 0;
|
||||
@include text-title-xs;
|
||||
|
||||
.vpn-monthly-price-display span {
|
||||
display: inline-block;
|
||||
font-weight: normal;
|
||||
@include text-body-md;
|
||||
}
|
||||
}
|
||||
|
||||
.c-pricing-block-mobile-currency-info {
|
||||
margin: $spacing-lg 0 0;
|
||||
@include text-body-sm;
|
||||
}
|
||||
|
||||
.c-pricing-block-mobile-total {
|
||||
color: $color-vpn-brand-refresh-gray;
|
||||
font-weight: bold;
|
||||
margin: $spacing-lg 0 0;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче