This commit is contained in:
185
src/django_deploy/tests/generic.py
Normal file
185
src/django_deploy/tests/generic.py
Normal file
@@ -0,0 +1,185 @@
|
||||
import importlib
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import unittest
|
||||
import mock
|
||||
import pytest
|
||||
|
||||
from ..config import DJANGO_SETTINGS_DIR
|
||||
|
||||
|
||||
class DjangoDeployTestCase(unittest.TestCase):
|
||||
@pytest.fixture(autouse=True)
|
||||
def tmpdir(self, tmpdir): # pylint: disable=method-hidden
|
||||
self.tmpdir = tmpdir
|
||||
|
||||
@staticmethod
|
||||
def _import_from_dir(module_name, directory):
|
||||
sys.path.insert(0, directory)
|
||||
module = importlib.import_module(module_name)
|
||||
if sys.version_info.major == 2: # pragma: no cover
|
||||
reload(module) # pylint: disable=undefined-variable
|
||||
else: # pragma: no cover
|
||||
importlib.reload(module) # pylint: disable=no-member
|
||||
sys.path.pop(0)
|
||||
return module
|
||||
|
||||
def get_django_settings(self, project_dir):
|
||||
module_name = 'settings'
|
||||
directory = os.path.join(project_dir, DJANGO_SETTINGS_DIR)
|
||||
return self._import_from_dir(module_name, directory)
|
||||
|
||||
def get_django_root_urlconf(self, project_dir):
|
||||
module_name = 'urls'
|
||||
directory = os.path.join(project_dir, DJANGO_SETTINGS_DIR)
|
||||
sys.modules['django.contrib'] = mock.MagicMock(name='django.contrib')
|
||||
return self._import_from_dir(module_name, directory)
|
||||
|
||||
def assert_django_project(self, project_dir):
|
||||
self.assertTrue(os.path.isdir(project_dir), 'no directory: {}'.format(project_dir))
|
||||
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_DIR)
|
||||
self.assertTrue(os.path.isdir(settings_dir), 'no directory: {}'.format(settings_dir))
|
||||
settings_file = os.path.join(settings_dir, 'settings.py')
|
||||
self.assertTrue(os.path.isfile(settings_file), 'no file: {}'.format(settings_file))
|
||||
manage_script = os.path.join(project_dir, 'manage.py')
|
||||
self.assertTrue(os.path.isfile(manage_script), 'no file: {}'.format(manage_script))
|
||||
|
||||
def assert_django_deploy_hooks(self, project_dir):
|
||||
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_DIR)
|
||||
settings_file = os.path.join(settings_dir, 'settings.py')
|
||||
urlconf_file = os.path.join(settings_dir, 'urls.py')
|
||||
django_deploy_json = os.path.join(settings_dir, 'django_deploy.json')
|
||||
|
||||
self.assertTrue(os.path.isfile(django_deploy_json), 'no file: {}'.format(django_deploy_json))
|
||||
|
||||
with open(settings_file, 'r') as f:
|
||||
needle = 'from django_deploy import get_installed_apps'
|
||||
haystack = f.read()
|
||||
self.assertIn(needle, haystack)
|
||||
|
||||
with open(urlconf_file, 'r') as f:
|
||||
needle = 'from django_deploy import get_urlpatterns'
|
||||
haystack = f.read()
|
||||
self.assertIn(needle, haystack)
|
||||
|
||||
def assert_no_django_deploy_hooks(self, project_dir):
|
||||
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_DIR)
|
||||
settings_file = os.path.join(settings_dir, 'settings.py')
|
||||
urlconf_file = os.path.join(settings_dir, 'urls.py')
|
||||
django_deploy_json = os.path.join(settings_dir, 'django_deploy.json')
|
||||
|
||||
self.assertFalse(os.path.isfile(django_deploy_json))
|
||||
|
||||
with open(settings_file, 'r') as f:
|
||||
needle = 'from django_deploy import get_installed_apps'
|
||||
haystack = f.read()
|
||||
self.assertNotIn(needle, haystack)
|
||||
|
||||
with open(urlconf_file, 'r') as f:
|
||||
needle = 'from django_deploy import get_urlpatterns'
|
||||
haystack = f.read()
|
||||
self.assertNotIn(needle, haystack)
|
||||
|
||||
def assert_text_in_settings(self, project_dir, settings_text):
|
||||
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_DIR)
|
||||
settings_file = os.path.join(settings_dir, 'settings.py')
|
||||
with open(settings_file, 'r') as f:
|
||||
complete_settings = f.read()
|
||||
self.assertIn(settings_text, complete_settings)
|
||||
|
||||
def assert_values_in_settings(self, project_dir, settings_dict):
|
||||
real_settings = self.get_django_settings(project_dir)
|
||||
for key in settings_dict:
|
||||
self.assertTrue(hasattr(real_settings, key))
|
||||
expected_value = settings_dict[key]
|
||||
real_value = getattr(real_settings, key)
|
||||
self.assertEqual(expected_value, real_value)
|
||||
|
||||
def assert_settings_from_apps(self, project_dir, apps):
|
||||
hooks_config_name = 'django_deploy_hooks'
|
||||
wsgi_application_provider = 'main'
|
||||
for app in apps:
|
||||
try:
|
||||
hooks_config = importlib.import_module('{}.{}'.format(app, hooks_config_name))
|
||||
except ImportError: # pragma: no cover
|
||||
continue
|
||||
if not hasattr(hooks_config, 'SETTINGS'):
|
||||
continue
|
||||
settings_text = getattr(hooks_config, 'SETTINGS')
|
||||
self.assert_text_in_settings(project_dir, settings_text)
|
||||
wsgi_application_provider = app
|
||||
|
||||
wsgi_application = '{}.wsgi.application'.format(wsgi_application_provider)
|
||||
self.assert_values_in_settings(project_dir, {'WSGI_APPLICATION': wsgi_application})
|
||||
|
||||
def assert_installed_apps(self, project_dir, apps, default_apps=None):
|
||||
settings = self.get_django_settings(project_dir)
|
||||
|
||||
if default_apps is None:
|
||||
expected_apps = [
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
]
|
||||
else: # pragma: no cover
|
||||
expected_apps = default_apps
|
||||
|
||||
expected_apps += apps
|
||||
|
||||
self.assertListEqual(expected_apps, settings.INSTALLED_APPS)
|
||||
self.assert_settings_from_apps(project_dir, apps)
|
||||
|
||||
def assert_urlpatterns(self, project_dir, patterns):
|
||||
root_urlconf = self.get_django_root_urlconf(project_dir)
|
||||
|
||||
# Django 2 vs Django 1
|
||||
if hasattr(root_urlconf, 'path'): # pragma: no cover
|
||||
expected_urlpatterns = [
|
||||
('URLPattern', 'admin/', 'django.contrib.admin.site.urls'),
|
||||
]
|
||||
else: # pragma: no cover
|
||||
expected_urlpatterns = [
|
||||
('URLPattern', '^admin/', 'django.contrib.admin.site.urls'),
|
||||
]
|
||||
expected_urlpatterns += patterns
|
||||
|
||||
real_urlpatterns = root_urlconf.urlpatterns
|
||||
self.assertEqual(len(expected_urlpatterns), len(real_urlpatterns))
|
||||
|
||||
for i, expected in enumerate(expected_urlpatterns):
|
||||
real = real_urlpatterns[i]
|
||||
real_class_name = real.__class__.__name__
|
||||
self.assertTrue(real_class_name.endswith(expected[0]))
|
||||
# Django 2 vs. Django 1
|
||||
if real_class_name == 'URLPattern': # pragma: no cover
|
||||
self.assertEqual(expected[1], str(real.pattern))
|
||||
self.assertTrue(real.callback.startswith("<Mock name='{}' id=".format(expected[2])))
|
||||
elif real_class_name == 'RegexURLPattern': # pragma: no cover
|
||||
self.assertEqual(expected[1], real.regex.pattern)
|
||||
self.assertTrue(real.callback.startswith("<Mock name='{}' id=".format(expected[2])))
|
||||
elif real_class_name == 'URLResolver': # pragma: no cover
|
||||
self.assertEqual(expected[1], str(real.pattern))
|
||||
self.assertEqual(expected[2], real.urlconf_name.__name__)
|
||||
elif real_class_name == 'RegexURLResolver': # pragma: no cover
|
||||
self.assertEqual(expected[1], real.regex.pattern)
|
||||
self.assertEqual(expected[2], real.urlconf_name.__name__)
|
||||
else: # pragma: no cover
|
||||
self.fail('Unknown urlpattern class: {}'.format(real_class_name))
|
||||
|
||||
def assert_django_database_migration(self, project_dir, app_label=None, migration=None):
|
||||
management_script = os.path.join(project_dir, 'manage.py')
|
||||
cmd = [
|
||||
management_script, 'migrate', '--no-color', '--noinput'
|
||||
]
|
||||
if app_label is not None:
|
||||
cmd.append(app_label)
|
||||
if migration is not None:
|
||||
cmd.append(migration)
|
||||
|
||||
output = subprocess.check_output(cmd)
|
||||
text = output.decode('utf8')
|
||||
self.assertTrue(text.endswith('No migrations to apply.\n'))
|
||||
Reference in New Issue
Block a user