from distutils.version import LooseVersion from unittest import mock from django.core.management import call_command, CommandError from django.test import TestCase import django class CommandsTestCase(TestCase): def test_processincomingmessage_no_args(self): """Check that processincomingmessage works with no args""" mailbox_name = None # Mock handle so that the test doesn't hang waiting for input. Note that we are only testing # the argument parsing here -- functionality should be tested elsewhere with mock.patch('django_mailbox.management.commands.processincomingmessage.Command.handle') as handle: # Don't care about the return value handle.return_value = None call_command('processincomingmessage') args, kwargs = handle.call_args # Make sure that we called with the right arguments try: self.assertEqual(kwargs['mailbox_name'], mailbox_name) except KeyError: # Handle Django 1.7 # It uses optparse instead of argparse, so instead of being # set to None, mailbox_name is simply left out altogether # Thus we expect an empty tuple here self.assertEqual(args, tuple()) def test_processincomingmessage_with_arg(self): """Check that processincomingmessage works with mailbox_name given""" mailbox_name = 'foo_mailbox' with mock.patch('django_mailbox.management.commands.processincomingmessage.Command.handle') as handle: handle.return_value = None call_command('processincomingmessage', mailbox_name) args, kwargs = handle.call_args try: self.assertEqual(kwargs['mailbox_name'], mailbox_name) except (AssertionError, KeyError): # Handle Django 1.7 # It uses optparse instead of argparse, so instead of being # in kwargs, mailbox_name is in args self.assertEqual(args[0], mailbox_name) def test_processincomingmessage_too_many_args(self): """Check that processincomingmessage raises an error if too many args""" # Only perform this test for Django versions greater than 1.7.*. This # is because, with optparse, too many arguments doesn't result in an # error, which means this test is worthless anyway # For the "compatibility" versions, unexpected arguments aren't handled # very well, and result in a TypeError if (LooseVersion(django.get_version()) >= LooseVersion('1.8') and LooseVersion(django.get_version()) < LooseVersion('1.10')): with self.assertRaises(TypeError): call_command('processincomingmessage', 'foo_mailbox', 'invalid_arg') # In 1.10 and later a proper CommandError should be raised elif LooseVersion(django.get_version()) >= LooseVersion('1.10'): with self.assertRaises(CommandError): call_command('processincomingmessage', 'foo_mailbox', 'invalid_arg')