From 57eb1d8c0f511e1b9312eb3503053d7d2ea1f2f7 Mon Sep 17 00:00:00 2001 From: Alexander Ivanov Date: Fri, 23 Feb 2018 12:04:41 +0300 Subject: [PATCH] Log an error or abort startup if apps cannot be imported. --- django_telegrambot/apps.py | 13 +++++---- tests/test_app/__init__.py | 0 tests/test_app/telegrambot.py | 1 + tests/test_apps.py | 48 +++++++++++++++++++++++++++++++ tests/test_bad_app/__init__.py | 0 tests/test_bad_app/telegrambot.py | 1 + 6 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 tests/test_app/__init__.py create mode 100644 tests/test_app/telegrambot.py create mode 100644 tests/test_apps.py create mode 100644 tests/test_bad_app/__init__.py create mode 100644 tests/test_bad_app/telegrambot.py diff --git a/django_telegrambot/apps.py b/django_telegrambot/apps.py index dd4ab80..1ffacbb 100644 --- a/django_telegrambot/apps.py +++ b/django_telegrambot/apps.py @@ -178,7 +178,7 @@ def ready(self): bot.more_info = webhook_info logger.info('Telegram Bot <{}> setting webhook [ {} ] max connections:{} allowed updates:{} pending updates:{} : {}'.format(bot.username, webhook_info.url, webhook_info.max_connections, real_allowed, webhook_info.pending_update_count, setted)) - + except InvalidToken: logger.error('Invalid Token : {}'.format(token)) return @@ -208,7 +208,7 @@ def ready(self): logger.debug('Telegram Bot <{}> set as default bot'.format(DjangoTelegramBot.bots[0].username)) - def module_exists(module_name, method_name, execute): + def module_imported(module_name, method_name, execute): try: m = importlib.import_module(module_name) if execute and hasattr(m, method_name): @@ -218,8 +218,11 @@ def module_exists(module_name, method_name, execute): logger.debug('Run {}'.format(module_name)) except ImportError as er: - logger.debug('{} : {}'.format(module_name, repr(er))) - return False + if settings.DJANGO_TELEGRAMBOT.get('STRICT_INIT'): + raise er + else: + logger.error('{} : {}'.format(module_name, repr(er))) + return False return True @@ -227,7 +230,7 @@ def module_exists(module_name, method_name, execute): for app_config in apps.get_app_configs(): if module_has_submodule(app_config.module, TELEGRAM_BOT_MODULE_NAME): module_name = '%s.%s' % (app_config.name, TELEGRAM_BOT_MODULE_NAME) - if module_exists(module_name, 'main', True): + if module_imported(module_name, 'main', True): logger.info('Loaded {}'.format(module_name)) num_bots=len(DjangoTelegramBot.__used_tokens) diff --git a/tests/test_app/__init__.py b/tests/test_app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_app/telegrambot.py b/tests/test_app/telegrambot.py new file mode 100644 index 0000000..6037672 --- /dev/null +++ b/tests/test_app/telegrambot.py @@ -0,0 +1 @@ +print("Import successful") diff --git a/tests/test_apps.py b/tests/test_apps.py new file mode 100644 index 0000000..a7ec71e --- /dev/null +++ b/tests/test_apps.py @@ -0,0 +1,48 @@ +import logging + +from django.apps.registry import Apps +from django.test import TestCase +from django_telegrambot.apps import DjangoTelegramBot +import mock + +logging.basicConfig(level=logging.INFO) + + +# Need to mock some of the Telegram Bot's methods with dummy values to make +# sure that the initialisation completes with mock credentials. +@mock.patch('telegram.bot.Bot.delete_webhook', lambda bot: None) +@mock.patch('telegram.bot.Bot.username', 'mock_bot') +@mock.patch('django_telegrambot.apps.DjangoTelegramBot.ready_run', False) +@mock.patch('django_telegrambot.apps.logger') +class TestDjangoTelegramBot(TestCase): + + def setUp(self): + self.app = DjangoTelegramBot.create('django_telegrambot') + + @mock.patch('django_telegrambot.apps.apps', + Apps(installed_apps=('tests.test_app',))) + def test_good_app_loading(self, log): + """Normal initialisation - should complete without error messages.""" + self.assertFalse(DjangoTelegramBot.ready_run) + self.app.ready() + self.assertEquals(log.error.call_count, 0) + self.assertTrue(DjangoTelegramBot.ready_run) + + @mock.patch('django_telegrambot.apps.apps', + Apps(installed_apps=('tests.test_bad_app',))) + def test_bad_app_loading(self, log): + """If a telegrambot.py module in some of the apps contains a mistake, + an error message should be loaded.""" + self.app.ready() + self.assertEquals(log.error.call_count, 1) + + @mock.patch('django_telegrambot.apps.apps', + Apps(installed_apps=('tests.test_bad_app',))) + @mock.patch.dict('django_telegrambot.apps.settings.DJANGO_TELEGRAMBOT', + STRICT_INIT=True) + def test_bad_app_loading_strict(self, _): + """With STRICT_INIT set to true in the DJANGO_TELEGRAMBOT settings, the + app must not start if the telegrambot.py files are not imported + successfully.""" + with self.assertRaises(ImportError): + self.app.ready() diff --git a/tests/test_bad_app/__init__.py b/tests/test_bad_app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_bad_app/telegrambot.py b/tests/test_bad_app/telegrambot.py new file mode 100644 index 0000000..f36e4fe --- /dev/null +++ b/tests/test_bad_app/telegrambot.py @@ -0,0 +1 @@ +raise ImportError()