From 669bf6c76e5bf703a152dfc004055f0c1233ce6a Mon Sep 17 00:00:00 2001 From: Antoine Nguyen Date: Sun, 23 Oct 2016 13:56:11 +0200 Subject: [PATCH 1/4] Add unit tests to cover the extension engine. --- modoboa/core/extensions.py | 19 +++--- modoboa/core/tests/__init__.py | 0 .../core/tests/stupid_extension_1/__init__.py | 0 .../stupid_extension_1/modo_extension.py | 20 ++++++ .../core/tests/stupid_extension_2/__init__.py | 0 .../stupid_extension_2/modo_extension.py | 20 ++++++ modoboa/core/tests/stupid_extension_2/urls.py | 3 + modoboa/core/{tests.py => tests/test_core.py} | 6 +- modoboa/core/tests/test_extensions.py | 63 +++++++++++++++++++ 9 files changed, 117 insertions(+), 14 deletions(-) create mode 100644 modoboa/core/tests/__init__.py create mode 100644 modoboa/core/tests/stupid_extension_1/__init__.py create mode 100644 modoboa/core/tests/stupid_extension_1/modo_extension.py create mode 100644 modoboa/core/tests/stupid_extension_2/__init__.py create mode 100644 modoboa/core/tests/stupid_extension_2/modo_extension.py create mode 100644 modoboa/core/tests/stupid_extension_2/urls.py rename modoboa/core/{tests.py => tests/test_core.py} (99%) create mode 100644 modoboa/core/tests/test_extensions.py diff --git a/modoboa/core/extensions.py b/modoboa/core/extensions.py index 6c29b2b27..78e8f36d1 100644 --- a/modoboa/core/extensions.py +++ b/modoboa/core/extensions.py @@ -5,7 +5,6 @@ from django.conf.urls import include class ModoExtension(object): - """ Base extension class. @@ -23,22 +22,23 @@ class ModoExtension(object): available_for_topredirection = False def infos(self): - return dict( - name=self.name, label=self.label, version=self.version, - description=self.description, url=self.url, - always_active=self.always_active - ) + """Information about this extension.""" + return { + "name": self.name, "label": self.label, "version": self.version, + "description": self.description, "url": self.url, + "always_active": self.always_active + } def load_initial_data(self): """Declare extension data in this method.""" pass def load(self): + """Add extension loading tasks in this method.""" pass class ExtensionsPool(object): - """The extensions manager""" def __init__(self): @@ -60,11 +60,8 @@ class ExtensionsPool(object): self.extensions[name]["instance"] = self.extensions[name]["cls"]() return self.extensions[name]["instance"] - def is_extension_installed(self, name): - """Check if an extension is installed ir not.""" - return name in settings.MODOBOA_APPS - def get_extension_infos(self, name): + """Return information about the specified extension.""" instance = self.get_extension(name) if instance is None: return None diff --git a/modoboa/core/tests/__init__.py b/modoboa/core/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/modoboa/core/tests/stupid_extension_1/__init__.py b/modoboa/core/tests/stupid_extension_1/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/modoboa/core/tests/stupid_extension_1/modo_extension.py b/modoboa/core/tests/stupid_extension_1/modo_extension.py new file mode 100644 index 000000000..6add2bf75 --- /dev/null +++ b/modoboa/core/tests/stupid_extension_1/modo_extension.py @@ -0,0 +1,20 @@ +"""A stupid extension used for tests.""" + +from modoboa.core import extensions + + +class StupidExtension1(extensions.ModoExtension): + """Stupid extension to use with tests.""" + + name = "stupid_extension_1" + label = "Stupid extension" + version = "1.0.0" + description = "A stupid extension" + + def load(self): + pass + + def load_initial_data(self): + pass + +extensions.exts_pool.register_extension(StupidExtension1) diff --git a/modoboa/core/tests/stupid_extension_2/__init__.py b/modoboa/core/tests/stupid_extension_2/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/modoboa/core/tests/stupid_extension_2/modo_extension.py b/modoboa/core/tests/stupid_extension_2/modo_extension.py new file mode 100644 index 000000000..e9485c922 --- /dev/null +++ b/modoboa/core/tests/stupid_extension_2/modo_extension.py @@ -0,0 +1,20 @@ +"""A stupid extension used for tests.""" + +from modoboa.core import extensions + + +class StupidExtension2(extensions.ModoExtension): + """Stupid extension to use with tests.""" + + name = "stupid_extension_2" + label = "Stupid extension" + version = "1.0.0" + description = "A stupid extension" + + def load(self): + pass + + def load_initial_data(self): + pass + +extensions.exts_pool.register_extension(StupidExtension2, show=False) diff --git a/modoboa/core/tests/stupid_extension_2/urls.py b/modoboa/core/tests/stupid_extension_2/urls.py new file mode 100644 index 000000000..552d09822 --- /dev/null +++ b/modoboa/core/tests/stupid_extension_2/urls.py @@ -0,0 +1,3 @@ +"""Custom urls.""" + +urlpatterns = [] diff --git a/modoboa/core/tests.py b/modoboa/core/tests/test_core.py similarity index 99% rename from modoboa/core/tests.py rename to modoboa/core/tests/test_core.py index de7774d91..598124fd9 100644 --- a/modoboa/core/tests.py +++ b/modoboa/core/tests/test_core.py @@ -13,9 +13,9 @@ from modoboa.lib import parameters from modoboa.lib.tests import ModoTestCase from modoboa.lib.tests import NO_LDAP -from . import factories -from . import mocks -from . import models +from .. import factories +from .. import mocks +from .. import models class AuthenticationTestCase(ModoTestCase): diff --git a/modoboa/core/tests/test_extensions.py b/modoboa/core/tests/test_extensions.py new file mode 100644 index 000000000..b48889215 --- /dev/null +++ b/modoboa/core/tests/test_extensions.py @@ -0,0 +1,63 @@ +"""Extensions management related test cases.""" + +import os +import sys + +from django.test import TestCase, override_settings + +from .. import extensions + +CUSTOM_APPS = ( + "modoboa", + "modoboa.core", + "modoboa.lib", + "modoboa.admin", + "modoboa.limits", + "modoboa.relaydomains", + "stupid_extension_1", + "stupid_extension_2", +) + +sys.path.append(os.path.dirname(__file__)) + + +class StupidExtension2(extensions.ModoExtension): + """Stupid extension to use with tests.""" + + name = "stupid_extension_2" + label = "Stupid extension" + version = "1.0.0" + description = "A stupid extension" + + def load(self): + pass + + def load_initial_data(self): + pass + + +@override_settings(MODOBOA_APPS=CUSTOM_APPS) +class ExtensionTestCase(TestCase): + """Extensions related tests.""" + + def setUp(self): + """Initiate test context.""" + self.pool = extensions.exts_pool + self.pool.load_all() + + def test_register(self): + """Test if registering works.""" + self.assertIn("stupid_extension_1", self.pool.extensions) + + def test_get_extension(self): + """Check getter method.""" + self.assertIsNone(self.pool.get_extension("toto")) + instance = self.pool.get_extension("stupid_extension_1") + self.assertEqual(instance.__class__.__name__, "StupidExtension1") + + def test_list_all(self): + """Check list_all method.""" + result = self.pool.list_all() + self.assertEqual(len(result), 1) + ext = result[0] + self.assertEqual(ext["id"], "stupid_extension_1") From 80d32f238908cdaa0d07d0fb303cc1d62b923837 Mon Sep 17 00:00:00 2001 From: Antoine Nguyen Date: Sun, 23 Oct 2016 14:03:08 +0200 Subject: [PATCH 2/4] Fix unit test. --- modoboa/admin/tests/test_account.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modoboa/admin/tests/test_account.py b/modoboa/admin/tests/test_account.py index ea3080ad4..e44914df6 100644 --- a/modoboa/admin/tests/test_account.py +++ b/modoboa/admin/tests/test_account.py @@ -6,7 +6,7 @@ from django.core.urlresolvers import reverse from django.test import override_settings from modoboa.core import factories as core_factories -from modoboa.core import tests as core_tests +from modoboa.core.tests import test_core from modoboa.core.models import User from modoboa.lib import parameters from modoboa.lib.tests import ModoTestCase @@ -221,7 +221,7 @@ class AccountTestCase(ModoTestCase): 'modoboa.lib.authbackends.LDAPBackend', 'modoboa.lib.authbackends.SimpleBackend', )) -class LDAPAccountTestCase(core_tests.LDAPTestCaseMixin, ModoTestCase): +class LDAPAccountTestCase(test_core.LDAPTestCaseMixin, ModoTestCase): """Check LDAP related code.""" def test_autocreate_disabled(self): From dae517e5e56ddef72334bbe060e499af03cd90f2 Mon Sep 17 00:00:00 2001 From: Antoine Nguyen Date: Sun, 23 Oct 2016 14:24:00 +0200 Subject: [PATCH 3/4] Increase coverage. --- .../tests/stupid_extension_1/modo_extension.py | 2 +- .../tests/stupid_extension_2/modo_extension.py | 6 ------ modoboa/core/tests/test_extensions.py | 18 ++++++++++++++++++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/modoboa/core/tests/stupid_extension_1/modo_extension.py b/modoboa/core/tests/stupid_extension_1/modo_extension.py index 6add2bf75..4cc7f4121 100644 --- a/modoboa/core/tests/stupid_extension_1/modo_extension.py +++ b/modoboa/core/tests/stupid_extension_1/modo_extension.py @@ -15,6 +15,6 @@ class StupidExtension1(extensions.ModoExtension): pass def load_initial_data(self): - pass + raise RuntimeError extensions.exts_pool.register_extension(StupidExtension1) diff --git a/modoboa/core/tests/stupid_extension_2/modo_extension.py b/modoboa/core/tests/stupid_extension_2/modo_extension.py index e9485c922..47824e924 100644 --- a/modoboa/core/tests/stupid_extension_2/modo_extension.py +++ b/modoboa/core/tests/stupid_extension_2/modo_extension.py @@ -11,10 +11,4 @@ class StupidExtension2(extensions.ModoExtension): version = "1.0.0" description = "A stupid extension" - def load(self): - pass - - def load_initial_data(self): - pass - extensions.exts_pool.register_extension(StupidExtension2, show=False) diff --git a/modoboa/core/tests/test_extensions.py b/modoboa/core/tests/test_extensions.py index b48889215..94fec8479 100644 --- a/modoboa/core/tests/test_extensions.py +++ b/modoboa/core/tests/test_extensions.py @@ -3,6 +3,9 @@ import os import sys +from testfixtures import compare + +from django.core import management from django.test import TestCase, override_settings from .. import extensions @@ -55,9 +58,24 @@ class ExtensionTestCase(TestCase): instance = self.pool.get_extension("stupid_extension_1") self.assertEqual(instance.__class__.__name__, "StupidExtension1") + def test_get_extension_infos(self): + """Check getter method.""" + self.assertIsNone(self.pool.get_extension_infos("toto")) + infos = self.pool.get_extension_infos("stupid_extension_1") + compare(infos, { + "name": "stupid_extension_1", "label": "Stupid extension", + "version": "1.0.0", "description": "A stupid extension", + "url": None, "always_active": False + }) + def test_list_all(self): """Check list_all method.""" result = self.pool.list_all() self.assertEqual(len(result), 1) ext = result[0] self.assertEqual(ext["id"], "stupid_extension_1") + + def test_load_initial_data(self): + """Check if method is called.""" + with self.assertRaises(RuntimeError): + management.call_command("load_initial_data") From 2b7f0b03d41516748ecbb823883ce8e4d79089c0 Mon Sep 17 00:00:00 2001 From: Antoine Nguyen Date: Sun, 23 Oct 2016 15:04:04 +0200 Subject: [PATCH 4/4] Make sure test extensions are not used elsewhere. --- modoboa/core/tests/test_extensions.py | 34 ++++++++++----------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/modoboa/core/tests/test_extensions.py b/modoboa/core/tests/test_extensions.py index 94fec8479..b99c1502c 100644 --- a/modoboa/core/tests/test_extensions.py +++ b/modoboa/core/tests/test_extensions.py @@ -10,6 +10,8 @@ from django.test import TestCase, override_settings from .. import extensions +sys.path.append(os.path.dirname(__file__)) + CUSTOM_APPS = ( "modoboa", "modoboa.core", @@ -21,32 +23,22 @@ CUSTOM_APPS = ( "stupid_extension_2", ) -sys.path.append(os.path.dirname(__file__)) - -class StupidExtension2(extensions.ModoExtension): - """Stupid extension to use with tests.""" - - name = "stupid_extension_2" - label = "Stupid extension" - version = "1.0.0" - description = "A stupid extension" - - def load(self): - pass - - def load_initial_data(self): - pass - - -@override_settings(MODOBOA_APPS=CUSTOM_APPS) class ExtensionTestCase(TestCase): """Extensions related tests.""" - def setUp(self): + @classmethod + def setUpClass(cls): """Initiate test context.""" - self.pool = extensions.exts_pool - self.pool.load_all() + cls.pool = extensions.exts_pool + with override_settings(MODOBOA_APPS=CUSTOM_APPS): + cls.pool.load_all() + + @classmethod + def tearDownClass(cls): + """Reset context.""" + del cls.pool.extensions["stupid_extension_1"] + del cls.pool.extensions["stupid_extension_2"] def test_register(self): """Test if registering works."""