Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #53 from jgmize/handle-parse_accept_lang_header-error

Handle parse_accept_lang_header error
  • Loading branch information...
commit 1ad0eb2d9f4b8538e563689253394dadcd392456 2 parents 2c60d63 + 358a5d9
@jgmize jgmize authored
Showing with 123 additions and 13 deletions.
  1. +12 −10 funfactory/urlresolvers.py
  2. +111 −3 tests/test_urlresolvers.py
View
22 funfactory/urlresolvers.py
@@ -98,16 +98,18 @@ def get_best_language(self, accept_lang):
langs = dict(LUM)
langs.update((k.split('-')[0], v) for k, v in LUM.items() if
k.split('-')[0] not in langs)
- ranked = parse_accept_lang_header(accept_lang)
- for lang, _ in ranked:
- lang = lang.lower()
- if lang in langs:
- return langs[lang]
- pre = lang.split('-')[0]
- if pre in langs:
- return langs[pre]
- # Could not find an acceptable language.
- return False
+ try:
+ ranked = parse_accept_lang_header(accept_lang)
+ except ValueError: # see https://code.djangoproject.com/ticket/21078
+ return
+ else:
+ for lang, _ in ranked:
+ lang = lang.lower()
+ if lang in langs:
+ return langs[lang]
+ pre = lang.split('-')[0]
+ if pre in langs:
+ return langs[pre]
def fix(self, path):
path = path.lstrip('/')
View
114 tests/test_urlresolvers.py
@@ -1,10 +1,13 @@
# -*- coding: utf-8 -*-
+from django.conf import settings
from django.conf.urls.defaults import patterns, url
from django.test import TestCase
+from django.test.client import RequestFactory
+from django.test.utils import override_settings
-from funfactory.urlresolvers import reverse, split_path
-from mock import patch
-from nose.tools import eq_
+from funfactory.urlresolvers import reverse, split_path, Prefixer
+from mock import patch, Mock
+from nose.tools import eq_, ok_
# split_path tests use a test generator, which cannot be used inside of a
@@ -54,3 +57,108 @@ def test_unicode_url(self, get_url_prefix):
# Ensure that UTF-8 characters are escaped properly.
self.assertEqual(result, '/Fran%C3%A7oi/test/')
self.assertEqual(type(result), str)
+
+
+class TestPrefixer(TestCase):
+ def setUp(self):
+ self.factory = RequestFactory()
+
+ @override_settings(LANGUAGE_CODE='en-US')
+ def test_get_language_default_language_code(self):
+ """
+ Should return default set by settings.LANGUAGE_CODE if no 'lang'
+ url parameter and no Accept-Language header
+ """
+ request = self.factory.get('/')
+ self.assertFalse('lang' in request.GET)
+ self.assertFalse(request.META.get('HTTP_ACCEPT_LANGUAGE'))
+ prefixer = Prefixer(request)
+ eq_(prefixer.get_language(), 'en-US')
+
+ @override_settings(LANGUAGE_URL_MAP={'en-us': 'en-US', 'de': 'de'})
+ def test_get_language_valid_lang_param(self):
+ """
+ Should return lang param value if it is in settings.LANGUAGE_URL_MAP
+ """
+ request = self.factory.get('/?lang=de')
+ eq_(request.GET.get('lang'), 'de')
+ ok_('de' in settings.LANGUAGE_URL_MAP)
+ prefixer = Prefixer(request)
+ eq_(prefixer.get_language(), 'de')
+
+ @override_settings(LANGUAGE_CODE='en-US',
+ LANGUAGE_URL_MAP={'en-us': 'en-US'})
+ def test_get_language_invalid_lang_param(self):
+ """
+ Should return default set by settings.LANGUAGE_CODE if lang
+ param value is not in settings.LANGUAGE_URL_MAP
+ """
+ request = self.factory.get('/?lang=de')
+ ok_('lang' in request.GET)
+ self.assertFalse('de' in settings.LANGUAGE_URL_MAP)
+ prefixer = Prefixer(request)
+ eq_(prefixer.get_language(), 'en-US')
+
+ def test_get_language_returns_best(self):
+ """
+ Should pass Accept-Language header value to get_best_language
+ and return result
+ """
+ request = self.factory.get('/')
+ request.META['HTTP_ACCEPT_LANGUAGE'] = 'de, es'
+ prefixer = Prefixer(request)
+ prefixer.get_best_language = Mock(return_value='de')
+ eq_(prefixer.get_language(), 'de')
+ prefixer.get_best_language.assert_called_once_with('de, es')
+
+ @override_settings(LANGUAGE_CODE='en-US')
+ def test_get_language_no_best(self):
+ """
+ Should return default set by settings.LANGUAGE_CODE if
+ get_best_language return value is None
+ """
+ request = self.factory.get('/')
+ request.META['HTTP_ACCEPT_LANGUAGE'] = 'de, es'
+ prefixer = Prefixer(request)
+ prefixer.get_best_language = Mock(return_value=None)
+ eq_(prefixer.get_language(), 'en-US')
+ prefixer.get_best_language.assert_called_once_with('de, es')
+
+ @override_settings(LANGUAGE_URL_MAP={'en-us': 'en-US', 'de': 'de'})
+ def test_get_best_language_exact_match(self):
+ """
+ Should return exact match if it is in settings.LANGUAGE_URL_MAP
+ """
+ request = self.factory.get('/')
+ prefixer = Prefixer(request)
+ eq_(prefixer.get_best_language('de, es'), 'de')
+
+ @override_settings(LANGUAGE_URL_MAP={'en-us': 'en-US', 'es-ar': 'es-AR'})
+ def test_get_best_language_prefix_match(self):
+ """
+ Should return a language with a matching prefix from
+ settings.LANGUAGE_URL_MAP if it exists but no exact match does
+ """
+ request = self.factory.get('/')
+ prefixer = Prefixer(request)
+ eq_(prefixer.get_best_language('es-CL'), 'es-AR')
+
+ @override_settings(LANGUAGE_URL_MAP={'en-us': 'en-US'})
+ def test_get_best_language_no_match(self):
+ """
+ Should return None if there is no exact match or matching
+ prefix
+ """
+ request = self.factory.get('/')
+ prefixer = Prefixer(request)
+ eq_(prefixer.get_best_language('de'), None)
+
+ @override_settings(LANGUAGE_URL_MAP={'en-us': 'en-US'})
+ def test_get_best_language_handles_parse_accept_lang_header_error(self):
+ """
+ Should return None despite error raised by bug described in
+ https://code.djangoproject.com/ticket/21078
+ """
+ request = self.factory.get('/')
+ prefixer = Prefixer(request)
+ eq_(prefixer.get_best_language('en; q=1,'), None)
Please sign in to comment.
Something went wrong with that request. Please try again.