Skip to content

Commit

Permalink
chore: Add missing tests
Browse files Browse the repository at this point in the history
  • Loading branch information
svillegas-cdd committed Oct 12, 2023
1 parent a16515b commit 9cc3a51
Showing 1 changed file with 150 additions and 1 deletion.
151 changes: 150 additions & 1 deletion tests/test_management.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,79 @@
import builtins
from io import StringIO
from unittest import skip

from django.core.management import call_command
from django.core.management import call_command, CommandError
from django.test import TestCase

from fd_dj_accounts import management
from fd_dj_accounts.management.commands import createsuperuser
from fd_dj_accounts.models import User


MOCK_INPUT_KEY_TO_PROMPTS = {
'bypass': ['Bypass password validation and create user anyway? [y/N]: '],
'email_address': ['Email address: '],
'password': ['Password: '],
}


def mock_inputs(inputs):
"""
Decorator to temporarily replace input/getpass to allow interactive
createsuperuser.
"""
def inner(test_func):
def wrapped(*args):
class mock_getpass:
@staticmethod
def getpass(prompt=b'Password: ', stream=None):
if callable(inputs['password']):
return inputs['password']()
return inputs['password']

def mock_input(prompt):
assert '__proxy__' not in prompt
response = None
for key, val in inputs.items():
if val == 'KeyboardInterrupt':
raise KeyboardInterrupt
# get() fallback because sometimes 'key' is the actual
# prompt rather than a shortcut name.
prompt_msgs = MOCK_INPUT_KEY_TO_PROMPTS.get(key, key)
if isinstance(prompt_msgs, list):
prompt_msgs = [msg() if callable(msg) else msg for msg in prompt_msgs]
if prompt in prompt_msgs:
if callable(val):
response = val()
else:
response = val
break
if response is None:
raise ValueError('Mock input for %r not found.' % prompt)
return response

old_getpass = createsuperuser.getpass
old_input = builtins.input
createsuperuser.getpass = mock_getpass
builtins.input = mock_input
try:
test_func(*args)
finally:
createsuperuser.getpass = old_getpass
builtins.input = old_input
return wrapped
return inner


class MockTTY:
"""
A fake stdin object that pretends to be a TTY to be used in conjunction
with mock_inputs.
"""
def isatty(self):
return True


class GetDefaultUsernameTestCase(TestCase):
def test_simple(self) -> None:
self.assertEqual(management.get_default_username(), '')
Expand Down Expand Up @@ -36,6 +103,88 @@ def test_basic_usage(self) -> None:
# created password should be unusable
self.assertFalse(u.has_usable_password())

def test_no_email_argument(self):
new_io = StringIO()
with self.assertRaisesMessage(CommandError, 'You must use --email_address with --noinput.'):
call_command('createsuperuser', interactive=False, stdout=new_io)

def test_skip_if_not_in_TTY(self):
"""
If the command is not called from a TTY, it should be skipped and a
message should be displayed
"""

class FakeStdin:
"""A fake stdin object that has isatty() return False."""

def isatty(self):
return False

out = StringIO()
call_command(
"createsuperuser",
stdin=FakeStdin(),
stdout=out,
interactive=True,
)

self.assertEqual(User._default_manager.count(), 0)
self.assertIn("Superuser creation skipped", out.getvalue())

def test_interactive_basic_usage(self):
@mock_inputs({
'email_address': 'new_user@somewhere.org',
'password': 'nopasswd',
})
def createsuperuser():
new_io = StringIO()
call_command(
"createsuperuser",
interactive=True,
email_address="new_user@somewhere.org",
stdout=new_io,
stdin=MockTTY(),
)
command_output = new_io.getvalue().strip()
self.assertEqual(command_output, 'Superuser created successfully.')

createsuperuser()

users = User.objects.filter(email_address="new_user@somewhere.org")
self.assertEqual(users.count(), 1)

@skip("When running this test, the command enters in an infinite loop.")
def test_unique_usermane_validation(self):
new_io = StringIO()
call_command(
"createsuperuser",
interactive=False,
email_address="new_user@somewhere.org",
stdout=new_io,
)

@mock_inputs({
'email_address': 'new_user@somewhere.org',
'password': 'nopasswd',
})
def createsuperuser():
new_io = StringIO()
with self.assertRaisesMessage(CommandError, 'That email address is already taken.'):
call_command(
"createsuperuser",
interactive=True,
email_address="new_user@somewhere.org",
stdout=new_io,
stdin=MockTTY(),
)
command_output = new_io.getvalue().strip()
self.assertEqual(command_output, 'Superuser created successfully.')

createsuperuser()

users = User.objects.filter(email_address="new_user@somewhere.org")
self.assertEqual(users.count(), 1)

# TODO: Add tests.
# See:
# - https://github.com/django/django/blob/3.2/tests/auth_tests/test_management.py#L253-L1036
Expand Down

0 comments on commit 9cc3a51

Please sign in to comment.