import importlib import os import sys import unittest import mock import pytest from ..config import DJANGO_SETTINGS_DIR from ..program import Program class ProgramTestCase(unittest.TestCase): @pytest.fixture(autouse=True) def tmpdir(self, tmpdir): # pylint: disable=method-hidden self.tmpdir = tmpdir 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_project(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 setUp(self): self._program = Program() self._project_dir = os.path.join(str(self.tmpdir), 'django') self._program(argv=['--create', self._project_dir]) def test_create_new_dir(self): project_dir = os.path.join(str(self.tmpdir), 'new_dir') exitval = self._program(argv=['-c', project_dir]) self.assertEqual(os.EX_OK, exitval, 'program() does not return os.EX_OK') self._assert_django_project(project_dir) self._assert_django_deploy_project(project_dir) def test_create_existing_empty_dir(self): project_dir = os.path.join(str(self.tmpdir), 'empty_dir') os.makedirs(project_dir) exitval = self._program(argv=['-c', project_dir]) self.assertEqual(os.EX_OK, exitval, 'program() does not return os.EX_OK') self._assert_django_project(project_dir) self._assert_django_deploy_project(project_dir) def test_create_existing_project_dir(self): exitval = self._program(argv=['-c', self._project_dir]) self.assertEqual(os.EX_NOPERM, exitval, 'program() does not return os.EX_NOPERM' ' when project directory is not empty') def test_enable_django_deploy(self): project_dir = os.path.join(str(self.tmpdir), 'pure_django') os.makedirs(project_dir) cmd = 'django-admin startproject {name} {path}'.format(name=DJANGO_SETTINGS_DIR, path=project_dir) os.system(cmd) self._program(argv=['--enable', project_dir]) self._assert_django_deploy_project(project_dir) def test_enable_django_deploy_twice(self): exitval = self._program(argv=['-e', self._project_dir]) self.assertEqual(os.EX_NOPERM, exitval, 'program() does not return os.EX_NOPERM' ' when django_deploy is already enabled') def test_merge_installed_apps(self): project_dir = self._project_dir argv = [ '-a', 'django_deploy', '-a', 'django_deploy.tests.fake_app1', '-a', 'django_deploy.tests.fake_app2', project_dir] self._program(argv=argv) settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_DIR) sys.path.insert(0, settings_dir) settings = importlib.import_module('settings') if sys.version_info.major == 2: # pragma: no cover reload(settings) # pylint: disable=undefined-variable else: # pragma: no cover importlib.reload(settings) # pylint: disable=no-member sys.path.pop(0) expected_installed_apps = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django_deploy.tests.fake_app1', 'django_deploy.tests.fake_app2', ] self.assertListEqual(expected_installed_apps, settings.INSTALLED_APPS) def test_merge_root_urlconf(self): project_dir = self._project_dir argv = [ '-a', 'django_deploy', '-a', 'django_deploy.tests.fake_app1', '-a', 'django_deploy.tests.fake_app2', project_dir] self._program(argv=argv) sys.modules['django.contrib'] = mock.MagicMock(name='django.contrib') settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_DIR) sys.path.insert(0, settings_dir) root_urlconf = importlib.import_module('urls') if sys.version_info.major == 2: # pragma: no cover reload(root_urlconf) # pylint: disable=undefined-variable else: # pragma: no cover importlib.reload(root_urlconf) # pylint: disable=no-member sys.path.pop(0) # 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 += [ ('URLResolver', '^fake1/', 'django_deploy.tests.fake_app1.urls'), ('URLResolver', '^fake2/', 'django_deploy.tests.fake_app2.urls'), ] 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("