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) importlib.reload(module) 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) 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])) if real_class_name == 'URLPattern': self.assertEqual(expected[1], str(real.pattern)) self.assertTrue(real.callback.startswith("