Fixed #19725 -- Made createsuperuser handle non-ascii prompts

Thanks Michisu for the report.
This commit is contained in:
Claude Paroz 2013-02-04 10:04:56 +01:00
parent fb606e10ac
commit 55c585f1c7
2 changed files with 61 additions and 17 deletions

View File

@ -11,6 +11,7 @@ from django.contrib.auth.management import get_default_username
from django.core import exceptions
from django.core.management.base import BaseCommand, CommandError
from django.db import DEFAULT_DB_ALIAS
from django.utils.encoding import force_str
from django.utils.six.moves import input
from django.utils.text import capfirst
@ -83,8 +84,9 @@ class Command(BaseCommand):
if not username:
input_msg = capfirst(self.username_field.verbose_name)
if default_username:
input_msg += " (leave blank to use '%s')" % default_username
raw_value = input(input_msg + ': ')
input_msg = "%s (leave blank to use '%s')" % (
input_msg, default_username)
raw_value = input(force_str('%s: ' % input_msg))
if default_username and raw_value == '':
raw_value = default_username
@ -107,7 +109,7 @@ class Command(BaseCommand):
field = self.UserModel._meta.get_field(field_name)
user_data[field_name] = options.get(field_name)
while user_data[field_name] is None:
raw_value = input(capfirst(field.verbose_name + ': '))
raw_value = input(force_str('%s: ' % capfirst(field.verbose_name)))
try:
user_data[field_name] = field.clean(raw_value, None)
except exceptions.ValidationError as e:

View File

@ -1,3 +1,6 @@
# -*- encoding: utf-8 -*-
from __future__ import unicode_literals
import locale
from django.contrib.auth import get_user_model
@ -12,6 +15,37 @@ from django.test.utils import override_settings
from django.utils.six import StringIO
def mock_inputs(inputs):
"""
Decorator to temporarily replace input/getpass to allow interactive
createsuperuser.
"""
def inner(test_func):
def wrapped(*args):
class mock_getpass:
pass
mock_getpass.getpass = staticmethod(lambda p=None: inputs['password'])
def mock_input(prompt):
# prompt should be encoded in Python 2. This line will raise an
# Exception if prompt contains unencoded non-ascii on Python 2.
prompt = str(prompt)
if str('leave blank to use') in prompt:
return inputs['username']
old_getpass = createsuperuser.getpass
old_input = createsuperuser.input
createsuperuser.getpass = mock_getpass
createsuperuser.input = mock_input
try:
test_func(*args)
finally:
createsuperuser.getpass = old_getpass
createsuperuser.input = old_input
return wrapped
return inner
@skipIfCustomUser
class BasicTestCase(TestCase):
def test_user(self):
@ -103,17 +137,17 @@ class BasicTestCase(TestCase):
self.assertEqual(u.email, 'joe2@somewhere.org')
self.assertFalse(u.has_usable_password())
new_io = StringIO()
call_command("createsuperuser",
interactive=False,
username="joe+admin@somewhere.org",
email="joe@somewhere.org",
stdout=new_io
verbosity=0
)
u = User.objects.get(username="joe+admin@somewhere.org")
self.assertEqual(u.email, 'joe@somewhere.org')
self.assertFalse(u.has_usable_password())
@mock_inputs({'password': "nopasswd"})
def test_createsuperuser_nolocale(self):
"""
Check that createsuperuser does not break when no locale is set. See
@ -121,39 +155,47 @@ class BasicTestCase(TestCase):
"""
old_getdefaultlocale = locale.getdefaultlocale
old_getpass = createsuperuser.getpass
try:
# Temporarily remove locale information
locale.getdefaultlocale = lambda: (None, None)
# Temporarily replace getpass to allow interactive code to be used
# non-interactively
class mock_getpass:
pass
mock_getpass.getpass = staticmethod(lambda p=None: "nopasswd")
createsuperuser.getpass = mock_getpass
# Call the command in this new environment
new_io = StringIO()
call_command("createsuperuser",
interactive=True,
username="nolocale@somewhere.org",
email="nolocale@somewhere.org",
stdout=new_io
verbosity=0
)
except TypeError:
self.fail("createsuperuser fails if the OS provides no information about the current locale")
finally:
# Re-apply locale and getpass information
createsuperuser.getpass = old_getpass
# Re-apply locale information
locale.getdefaultlocale = old_getdefaultlocale
# If we were successful, a user should have been created
u = User.objects.get(username="nolocale@somewhere.org")
self.assertEqual(u.email, 'nolocale@somewhere.org')
@mock_inputs({'password': "nopasswd", 'username': 'foo'})
def test_createsuperuser_non_ascii_verbose_name(self):
username_field = User._meta.get_field('username')
old_verbose_name = username_field.verbose_name
username_field.verbose_name = 'uživatel'
new_io = StringIO()
try:
call_command("createsuperuser",
interactive=True,
email="nolocale@somewhere.org",
stdout=new_io
)
finally:
username_field.verbose_name = old_verbose_name
command_output = new_io.getvalue().strip()
self.assertEqual(command_output, 'Superuser created successfully.')
def test_get_user_model(self):
"The current user model can be retrieved"
self.assertEqual(get_user_model(), User)