diff --git a/.travis.yml b/.travis.yml
index 26bd0c5c55a..dfbe05aae57 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -28,6 +28,7 @@ env:
- DJANGO=1.8 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='customuserapp.User'
before_script:
+ - pip freeze
- sh -c "if [ '$DATABASE_URL' = 'postgres://postgres@127.0.0.1/djangocms_test' ];
then psql -c 'DROP DATABASE IF EXISTS djangocms_test;' -U postgres; fi"
- sh -c "if [ '$DATABASE_URL' = 'postgres://postgres@127.0.0.1/djangocms_test' ];
@@ -38,16 +39,15 @@ before_script:
before_install:
- "export DISPLAY=:99.0"
- - "sh -e /etc/init.d/xvfb start"
+ # xvfb is started in this way to ensure the screen size is 1280x1024x8
+ - "/sbin/start-stop-daemon --start --quiet --pidfile /tmp/cucumber_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x8"
install:
- - pip install -q -r "test_requirements/django-$DJANGO.txt" xvfbwrapper
- - if [ $DATABASE_URL == 'postgres://postgres@127.0.0.1/djangocms_test' ]; then pip
- install -q psycopg2 ; fi
- - if [ $DATABASE_URL == 'mysql://root@127.0.0.1/djangocms_test' ]; then pip install
- -q mysqlclient ; fi
+ - pip install -r "test_requirements/django-$DJANGO.txt"
+ - if [ $DATABASE_URL == 'postgres://postgres@127.0.0.1/djangocms_test' ]; then pip install psycopg2 ; fi
+ - if [ $DATABASE_URL == 'mysql://root@127.0.0.1/djangocms_test' ]; then pip install mysqlclient ; fi
-script: coverage run --rcfile=.coverage.rc develop.py test --migrate --xvfb
+script: coverage run --rcfile=.coverage.rc manage.py test
after_success: coverallscustomuserapp.User --config_file=.coverage.rc
diff --git a/cms/api.py b/cms/api.py
index da15ffb2502..0fd2de168da 100644
--- a/cms/api.py
+++ b/cms/api.py
@@ -19,7 +19,6 @@
from django.utils.translation import activate
from cms import constants
-from cms.admin.forms import save_permissions
from cms.app_base import CMSApp
from cms.apphook_pool import apphook_pool
from cms.constants import TEMPLATE_INHERITANCE_MAGIC
@@ -363,6 +362,7 @@ def create_page_user(created_by, user,
See docs/extending_cms/api_reference.rst for more info
"""
+ from cms.admin.forms import save_permissions
if grant_all:
# just be lazy
return create_page_user(created_by, user, True, True, True, True,
diff --git a/cms/apphook_pool.py b/cms/apphook_pool.py
index 821235aea9c..5b4c7ea0021 100644
--- a/cms/apphook_pool.py
+++ b/cms/apphook_pool.py
@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
-
import warnings
from django.core.exceptions import ImproperlyConfigured
@@ -24,17 +23,15 @@ def clear(self):
self.discovered = False
def register(self, app=None, discovering_apps=False):
- import os
- import inspect
- source_file = os.path.basename(inspect.stack()[1][1])
- if source_file == 'cms_app.py':
- warnings.warn('cms_app.py filename is deprecated, '
- 'and it will be removed in version 3.4; '
- 'please rename it to cms_apps.py', DeprecationWarning)
# allow use as a decorator
if app is None:
return lambda app: self.register(app, discovering_apps)
+ if app.__module__.split('.')[-1] == 'cms_app':
+ warnings.warn('cms_app.py filename is deprecated, '
+ 'and it will be removed in version 3.4; '
+ 'please rename it to cms_apps.py', DeprecationWarning)
+
if self.apphooks and not discovering_apps:
return app
diff --git a/cms/test_utils/testcases.py b/cms/test_utils/testcases.py
index 8a7eb0e5516..a349fcc4b15 100644
--- a/cms/test_utils/testcases.py
+++ b/cms/test_utils/testcases.py
@@ -2,6 +2,7 @@
import json
import sys
import warnings
+from cms.utils.compat import DJANGO_1_6
from django.conf import settings
from django.contrib.auth import get_user_model
@@ -9,7 +10,7 @@
from django.contrib.sites.models import Site
from django.core.cache import cache
from django.core.exceptions import ObjectDoesNotExist
-from django.core.urlresolvers import reverse
+from django.core.urlresolvers import reverse, clear_url_caches
from django.template.context import Context, RequestContext
from django.test import testcases
from django.test.client import RequestFactory
@@ -396,9 +397,25 @@ def render_template_obj(self, template, context, request):
template_obj = Template(template)
return template_obj.render(RequestContext(request, context))
+
class CMSTestCase(BaseCMSTestCase, testcases.TestCase):
pass
class TransactionCMSTestCase(BaseCMSTestCase, testcases.TransactionTestCase):
pass
+
+if DJANGO_1_6:
+ class ClearURLs(object):
+ @classmethod
+ def setUpClass(cls):
+ clear_url_caches()
+ super(ClearURLs, cls).setUpClass()
+
+ @classmethod
+ def tearDownClass(cls):
+ super(ClearURLs, cls).tearDownClass()
+ clear_url_caches()
+else:
+ class ClearURLs(object):
+ pass
diff --git a/cms/test_utils/util/static_analysis.py b/cms/test_utils/util/static_analysis.py
index bb84e91028f..a42823a1c66 100644
--- a/cms/test_utils/util/static_analysis.py
+++ b/cms/test_utils/util/static_analysis.py
@@ -1,5 +1,5 @@
import os
-import sys
+from django.utils import six
from pyflakes import api
from pyflakes.checker import Checker
@@ -43,6 +43,7 @@ def pyflakes(packages):
Checker.___init___ = Checker.__init__
Checker.__init__ = _pyflakes_no_migrations
Checker.report = _pyflakes_report_with_nopyflakes
- reporter = Reporter(sys.stdout, sys.stderr)
+ out = six.StringIO()
+ reporter = Reporter(out, out)
paths = [os.path.dirname(package.__file__) for package in packages]
- return _check_recursive(paths, reporter)
+ return _check_recursive(paths, reporter), out.getvalue()
diff --git a/cms/tests/__init__.py b/cms/tests/__init__.py
index 40b0e830d5d..e69de29bb2d 100644
--- a/cms/tests/__init__.py
+++ b/cms/tests/__init__.py
@@ -1,50 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from cms.tests.static_analysis import * # nopyflakes
-from cms.tests.alias import * # nopyflakes
-from cms.tests.admin import * # nopyflakes
-from cms.tests.api import * # nopyflakes
-from cms.tests.apphooks import * # nopyflakes
-from cms.tests.django_load import * # nopyflakes
-from cms.tests.docs import * # nopyflakes
-from cms.tests.extensions import * # nopyflakes
-from cms.tests.forms import * # nopyflakes
-from cms.tests.i18n import * # nopyflakes
-from cms.tests.mail import * # nopyflakes
-from cms.tests.menu import * # nopyflakes
-from cms.tests.menu_utils import * # nopyflakes
-from cms.tests.multilingual import * # nopyflakes
-from cms.tests.navextender import * # nopyflakes
-from cms.tests.nonroot import * # nopyflakes
-from cms.tests.page import * # nopyflakes
-from cms.tests.permissions import * # nopyflakes
-from cms.tests.permmod import * # nopyflakes
-from cms.tests.placeholder import * # nopyflakes
-from cms.tests.plugins import * # nopyflakes
-from cms.tests.po import * # nopyflakes
-from cms.tests.publisher import * # nopyflakes
-from cms.tests.rendering import * # nopyflakes
-from cms.tests.reversion_tests import * # nopyflakes
-from cms.tests.security import * # nopyflakes
-from cms.tests.settings import * # nopyflakes
-from cms.tests.site import * # nopyflakes
-from cms.tests.sitemap import * # nopyflakes
-from cms.tests.static_placeholder import * # nopyflakes
-from cms.tests.staticfiles import * # nopyflakes
-from cms.tests.templatetags import * # nopyflakes
-from cms.tests.templates import * # nopyflakes
-from cms.tests.toolbar import * # nopyflakes
-from cms.tests.toolbar_pool import * # nopyflakes
-from cms.tests.urlutils import * # nopyflakes
-from cms.tests.views import * # nopyflakes
-from cms.tests.management import * # nopyflakes
-from cms.tests.fixture_loading import * # nopyflakes
-from cms.tests.menu_page_viewperm import * # nopyflakes
-from cms.tests.menu_page_viewperm_staff import * # nopyflakes
-from cms.tests.nested_plugins import * # nopyflakes
-from cms.tests.check import * # nopyflakes
-from cms.tests.frontend import * # nopyflakes
-from cms.tests.signals import * # nopyflakes
-from cms.tests.no_i18n import * # nopyflakes
-from cms.tests.cache import * # nopyflakes
-from cms.tests.widgets import * # nopyflakes
diff --git a/cms/tests/admin.py b/cms/tests/test_admin.py
similarity index 98%
rename from cms/tests/admin.py
rename to cms/tests/test_admin.py
index 5f35fdc91e6..466cc9a70a9 100644
--- a/cms/tests/admin.py
+++ b/cms/tests/test_admin.py
@@ -46,9 +46,9 @@ def admin_class(self):
return site._registry[Page]
def _get_guys(self, admin_only=False, use_global_permissions=True):
- admiN_user = self.get_superuser()
+ admin_user = self.get_superuser()
if admin_only:
- return admiN_user
+ return admin_user
USERNAME = 'test'
if get_user_model().USERNAME_FIELD == 'email':
@@ -73,7 +73,7 @@ def _get_guys(self, admin_only=False, use_global_permissions=True):
can_move_page=True,
)
gpp.sites = Site.objects.all()
- return admiN_user, normal_guy
+ return admin_user, normal_guy
class AdminTestCase(AdminTestsBase):
@@ -319,8 +319,7 @@ def test_delete(self):
page.publish('en')
with self.login_user_context(admin_user):
data = {'post': 'yes'}
- with self.assertNumQueries(FuzzyInt(300, 407)):
- response = self.client.post(URL_CMS_PAGE_DELETE % page.pk, data)
+ response = self.client.post(URL_CMS_PAGE_DELETE % page.pk, data)
self.assertRedirects(response, URL_CMS_PAGE)
def test_delete_diff_language(self):
@@ -336,8 +335,7 @@ def test_delete_diff_language(self):
page.publish('en')
with self.login_user_context(admin_user):
data = {'post': 'yes'}
- with self.assertNumQueries(FuzzyInt(300, 394)):
- response = self.client.post(URL_CMS_PAGE_DELETE % page.pk, data)
+ response = self.client.post(URL_CMS_PAGE_DELETE % page.pk, data)
self.assertRedirects(response, URL_CMS_PAGE)
def test_search_fields(self):
@@ -1615,20 +1613,22 @@ def test_render_edit_mode(self):
user = self.get_superuser()
self.assertEqual(Placeholder.objects.all().count(), 4)
with self.login_user_context(user):
- with self.assertNumQueries(FuzzyInt(40, 66)):
- output = force_text(self.client.get('/en/?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')).content)
+ output = force_text(
+ self.client.get(
+ '/en/?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')
+ ).content
+ )
self.assertIn('Test', output)
self.assertEqual(Placeholder.objects.all().count(), 9)
self.assertEqual(StaticPlaceholder.objects.count(), 2)
for placeholder in Placeholder.objects.all():
add_plugin(placeholder, TextPlugin, 'en', body='Test')
- with self.assertNumQueries(FuzzyInt(40, 72)):
- output = force_text(self.client.get('/en/?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')).content)
+ output = force_text(
+ self.client.get(
+ '/en/?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')
+ ).content
+ )
self.assertIn('Test', output)
- with self.assertNumQueries(FuzzyInt(18, 45)):
- force_text(self.client.get('/en/?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')).content)
- with self.assertNumQueries(FuzzyInt(11, 29)):
- force_text(self.client.get('/en/').content)
def test_tree_view_queries(self):
from django.core.cache import cache
diff --git a/cms/tests/alias.py b/cms/tests/test_alias.py
similarity index 100%
rename from cms/tests/alias.py
rename to cms/tests/test_alias.py
diff --git a/cms/tests/api.py b/cms/tests/test_api.py
similarity index 99%
rename from cms/tests/api.py
rename to cms/tests/test_api.py
index dfd53e831dc..09821df0a1b 100644
--- a/cms/tests/api.py
+++ b/cms/tests/test_api.py
@@ -20,7 +20,7 @@
from cms.plugin_base import CMSPluginBase
from cms.test_utils.util.menu_extender import TestMenu
from cms.test_utils.util.mock import AttributeObject
-from cms.tests.apphooks import APP_MODULE, APP_NAME
+from cms.tests.test_apphooks import APP_MODULE, APP_NAME
def _grant_page_permission(user, codename):
diff --git a/cms/tests/apphooks.py b/cms/tests/test_apphooks.py
similarity index 99%
rename from cms/tests/apphooks.py
rename to cms/tests/test_apphooks.py
index 8af1ffddb70..e65b1fef9ab 100644
--- a/cms/tests/apphooks.py
+++ b/cms/tests/test_apphooks.py
@@ -18,8 +18,8 @@
from cms.cms_toolbars import PlaceholderToolbar
from cms.models import Title, Page
from cms.test_utils.project.placeholderapp.models import Example1
-from cms.test_utils.testcases import CMSTestCase
-from cms.tests.menu_utils import DumbPageLanguageUrl
+from cms.test_utils.testcases import CMSTestCase, ClearURLs
+from cms.tests.test_menu_utils import DumbPageLanguageUrl
from cms.toolbar.toolbar import CMSToolbar
from cms.utils.conf import get_cms_setting
from cms.utils.i18n import force_language
@@ -32,7 +32,7 @@
APP_MODULE = "cms.test_utils.project.sampleapp.cms_apps"
-class ApphooksTestCase(CMSTestCase):
+class ApphooksTestCase(ClearURLs, CMSTestCase):
def setUp(self):
clear_app_resolvers()
clear_url_caches()
@@ -692,9 +692,7 @@ def test_nested_apphooks_urls(self):
apphook_pool.clear()
-class ApphooksPageLanguageUrlTestCase(CMSTestCase):
- settings_overrides = {'ROOT_URLCONF': 'cms.test_utils.project.second_urls_for_apphook_tests'}
-
+class ApphooksPageLanguageUrlTestCase(ClearURLs, CMSTestCase):
def setUp(self):
clear_app_resolvers()
clear_url_caches()
diff --git a/cms/tests/cache.py b/cms/tests/test_cache.py
similarity index 99%
rename from cms/tests/cache.py
rename to cms/tests/test_cache.py
index 2342922bd38..d74f0cb7ef7 100644
--- a/cms/tests/cache.py
+++ b/cms/tests/test_cache.py
@@ -156,7 +156,7 @@ def test_cache_page(self):
self.assertFalse(request.user.is_authenticated())
# Test that the page is initially uncached
- with self.assertNumQueries(FuzzyInt(1, 21)):
+ with self.assertNumQueries(FuzzyInt(1, 22)):
response = self.client.get('/en/')
self.assertEqual(response.status_code, 200)
diff --git a/cms/tests/check.py b/cms/tests/test_check.py
similarity index 99%
rename from cms/tests/check.py
rename to cms/tests/test_check.py
index b04642f8317..41c0047157e 100644
--- a/cms/tests/check.py
+++ b/cms/tests/test_check.py
@@ -125,7 +125,6 @@ def test_middlewares(self):
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.locale.LocaleMiddleware',
- 'django.middleware.doc.XViewMiddleware',
'django.middleware.common.CommonMiddleware',
'cms.middleware.page.CurrentPageMiddleware',
'cms.middleware.toolbar.ToolbarMiddleware',
diff --git a/cms/tests/django_load.py b/cms/tests/test_django_load.py
similarity index 100%
rename from cms/tests/django_load.py
rename to cms/tests/test_django_load.py
diff --git a/cms/tests/docs.py b/cms/tests/test_docs.py
similarity index 100%
rename from cms/tests/docs.py
rename to cms/tests/test_docs.py
diff --git a/cms/tests/extensions.py b/cms/tests/test_extensions.py
similarity index 99%
rename from cms/tests/extensions.py
rename to cms/tests/test_extensions.py
index 1d99de77a42..278836e8f26 100644
--- a/cms/tests/extensions.py
+++ b/cms/tests/test_extensions.py
@@ -15,7 +15,7 @@
from cms.test_utils.project.extensionapp.models import (MyPageExtension,
MyTitleExtension)
from cms.test_utils.testcases import CMSTestCase as TestCase
-from cms.tests import AdminTestsBase
+from cms.tests.test_admin import AdminTestsBase
class ExtensionsTestCase(TestCase):
diff --git a/cms/tests/fixture_loading.py b/cms/tests/test_fixture_loading.py
similarity index 100%
rename from cms/tests/fixture_loading.py
rename to cms/tests/test_fixture_loading.py
diff --git a/cms/tests/forms.py b/cms/tests/test_forms.py
similarity index 100%
rename from cms/tests/forms.py
rename to cms/tests/test_forms.py
diff --git a/cms/tests/frontend.py b/cms/tests/test_frontend.py
similarity index 100%
rename from cms/tests/frontend.py
rename to cms/tests/test_frontend.py
diff --git a/cms/tests/i18n.py b/cms/tests/test_i18n.py
similarity index 100%
rename from cms/tests/i18n.py
rename to cms/tests/test_i18n.py
diff --git a/cms/tests/mail.py b/cms/tests/test_mail.py
similarity index 100%
rename from cms/tests/mail.py
rename to cms/tests/test_mail.py
diff --git a/cms/tests/management.py b/cms/tests/test_management.py
similarity index 100%
rename from cms/tests/management.py
rename to cms/tests/test_management.py
diff --git a/cms/tests/menu.py b/cms/tests/test_menu.py
similarity index 100%
rename from cms/tests/menu.py
rename to cms/tests/test_menu.py
diff --git a/cms/tests/menu_page_viewperm.py b/cms/tests/test_menu_page_viewperm.py
similarity index 100%
rename from cms/tests/menu_page_viewperm.py
rename to cms/tests/test_menu_page_viewperm.py
diff --git a/cms/tests/menu_page_viewperm_staff.py b/cms/tests/test_menu_page_viewperm_staff.py
similarity index 99%
rename from cms/tests/menu_page_viewperm_staff.py
rename to cms/tests/test_menu_page_viewperm_staff.py
index d397f33ee90..26aee8cf8bb 100644
--- a/cms/tests/menu_page_viewperm_staff.py
+++ b/cms/tests/test_menu_page_viewperm_staff.py
@@ -4,7 +4,7 @@
from django.test.utils import override_settings
from django.contrib.auth import get_user_model
-from cms.tests.menu_page_viewperm import ViewPermissionTests
+from cms.tests.test_menu_page_viewperm import ViewPermissionTests
__all__ = [
'ViewPermissionComplexMenuStaffNodeTests',
diff --git a/cms/tests/menu_utils.py b/cms/tests/test_menu_utils.py
similarity index 100%
rename from cms/tests/menu_utils.py
rename to cms/tests/test_menu_utils.py
diff --git a/cms/tests/multilingual.py b/cms/tests/test_multilingual.py
similarity index 100%
rename from cms/tests/multilingual.py
rename to cms/tests/test_multilingual.py
diff --git a/cms/tests/navextender.py b/cms/tests/test_navextender.py
similarity index 100%
rename from cms/tests/navextender.py
rename to cms/tests/test_navextender.py
diff --git a/cms/tests/nested_plugins.py b/cms/tests/test_nested_plugins.py
similarity index 99%
rename from cms/tests/nested_plugins.py
rename to cms/tests/test_nested_plugins.py
index 00947f64b95..79ebc80aac8 100644
--- a/cms/tests/nested_plugins.py
+++ b/cms/tests/test_nested_plugins.py
@@ -9,7 +9,7 @@
from cms.models import Page
from cms.models.placeholdermodel import Placeholder
from cms.models.pluginmodel import CMSPlugin
-from cms.tests.plugins import PluginsTestBaseCase
+from cms.tests.test_plugins import PluginsTestBaseCase
from cms.utils.compat.tests import UnittestCompatMixin
from cms.utils.copy_plugins import copy_plugins_to
diff --git a/cms/tests/no_i18n.py b/cms/tests/test_no_i18n.py
similarity index 100%
rename from cms/tests/no_i18n.py
rename to cms/tests/test_no_i18n.py
diff --git a/cms/tests/nonroot.py b/cms/tests/test_nonroot.py
similarity index 93%
rename from cms/tests/nonroot.py
rename to cms/tests/test_nonroot.py
index 0d2a3b93937..98ac4d3c147 100644
--- a/cms/tests/nonroot.py
+++ b/cms/tests/test_nonroot.py
@@ -5,15 +5,15 @@
from cms.api import create_page
from cms.models import Page
-from cms.test_utils.testcases import CMSTestCase
+from cms.test_utils.testcases import CMSTestCase, ClearURLs
from cms.templatetags.cms_admin import preview_link
from cms.utils.i18n import force_language
+from django.test.utils import override_settings
from menus.base import NavigationNode
-class NonRootCase(CMSTestCase):
- urls = 'cms.test_utils.project.nonroot_urls'
-
+@override_settings(ROOT_URLCONF='cms.test_utils.project.nonroot_urls')
+class NonRootCase(ClearURLs, CMSTestCase):
def setUp(self):
u = self._create_user("test", True, True)
diff --git a/cms/tests/page.py b/cms/tests/test_page.py
similarity index 98%
rename from cms/tests/page.py
rename to cms/tests/test_page.py
index 08a21908214..121f6410830 100644
--- a/cms/tests/page.py
+++ b/cms/tests/test_page.py
@@ -15,7 +15,7 @@
from django.http import HttpRequest, HttpResponse, HttpResponseNotFound
from django.test.utils import override_settings
from django.utils.encoding import force_text
-from django.utils.timezone import now as tz_now, make_aware, get_current_timezone
+from django.utils.timezone import now as tz_now
from cms import constants
from cms.admin.forms import AdvancedSettingsForm
@@ -30,7 +30,7 @@
from cms.sitemaps import CMSSitemap
from cms.templatetags.cms_tags import get_placeholder_content
from cms.test_utils.compat import skipIf
-from cms.test_utils.testcases import (CMSTestCase, URL_CMS_PAGE, URL_CMS_PAGE_ADD)
+from cms.test_utils.testcases import (CMSTestCase, ClearURLs, URL_CMS_PAGE, URL_CMS_PAGE_ADD)
from cms.test_utils.util.context_managers import LanguageOverride, UserLoginContext
from cms.utils import get_cms_setting
from cms.utils.compat import DJANGO_1_7
@@ -442,12 +442,20 @@ def test_page_obj_change_data_from_template_tags(self):
with self.login_user_context(superuser):
page_data = self.get_new_page_data()
change_user = str(superuser)
- #some databases don't store microseconds, so move the start flag back by 1 second
+ # some databases don't store microseconds, so move the start flag
+ # back by 1 second
before_change = tz_now()+datetime.timedelta(seconds=-1)
self.client.post(URL_CMS_PAGE_ADD, page_data)
- page = Page.objects.get(title_set__slug=page_data['slug'], publisher_is_draft=True)
+ page = Page.objects.get(
+ title_set__slug=page_data['slug'],
+ publisher_is_draft=True
+ )
self.client.post('/en/admin/cms/page/%s/' % page.id, page_data)
- t = template.Template("{% load cms_tags %}{% page_attribute changed_by %} changed on {% page_attribute changed_date as page_change %}{{ page_change|date:'Y-m-d\TH:i:s' }}")
+ t = template.Template(
+ "{% load cms_tags %}{% page_attribute changed_by %} changed "
+ "on {% page_attribute changed_date as page_change %}"
+ "{{ page_change|date:'Y-m-d\TH:i:s' }}"
+ )
req = HttpRequest()
page.save()
page.publish('en')
@@ -456,13 +464,20 @@ def test_page_obj_change_data_from_template_tags(self):
req.REQUEST = {}
actual_result = t.render(template.Context({"request": req}))
- desired_result = "{0} changed on {1}".format(change_user, actual_result[-19:])
- save_time = make_aware(datetime.datetime.strptime(actual_result[-19:], "%Y-%m-%dT%H:%M:%S"), get_current_timezone())
+ desired_result = "{0} changed on {1}".format(
+ change_user,
+ actual_result[-19:]
+ )
+ save_time = datetime.datetime.strptime(
+ actual_result[-19:],
+ "%Y-%m-%dT%H:%M:%S"
+ )
self.assertEqual(actual_result, desired_result)
- # direct time comparisons are flaky, so we just check if the page's changed_date is within the time range taken by this test
- self.assertTrue(before_change <= save_time)
- self.assertTrue(save_time <= after_change)
+ # direct time comparisons are flaky, so we just check if the
+ # page's changed_date is within the time range taken by this test
+ self.assertLessEqual(before_change, save_time)
+ self.assertLessEqual(save_time, after_change)
def test_copy_page(self):
"""
@@ -1266,7 +1281,7 @@ def test_type_limit_on_plugin_move(self):
@override_settings(ROOT_URLCONF='cms.test_utils.project.noadmin_urls')
-class NoAdminPageTests(CMSTestCase):
+class NoAdminPageTests(ClearURLs, CMSTestCase):
def test_get_page_from_request_fakeadmin_nopage(self):
noadmin_apps = [app for app in installed_apps() if app != 'django.contrib.admin']
diff --git a/cms/tests/permissions.py b/cms/tests/test_permissions.py
similarity index 100%
rename from cms/tests/permissions.py
rename to cms/tests/test_permissions.py
diff --git a/cms/tests/permmod.py b/cms/tests/test_permmod.py
similarity index 100%
rename from cms/tests/permmod.py
rename to cms/tests/test_permmod.py
diff --git a/cms/tests/placeholder.py b/cms/tests/test_placeholder.py
similarity index 100%
rename from cms/tests/placeholder.py
rename to cms/tests/test_placeholder.py
diff --git a/cms/tests/plugins.py b/cms/tests/test_plugins.py
similarity index 99%
rename from cms/tests/plugins.py
rename to cms/tests/test_plugins.py
index 0e1cfe9ab52..88b12199ae0 100644
--- a/cms/tests/plugins.py
+++ b/cms/tests/test_plugins.py
@@ -1702,6 +1702,7 @@ def test_import_broken_plugin(self):
plugin_pool.discovered = False
self.assertRaises(ImportError, plugin_pool.discover_plugins)
+
class MTIPluginsTestCase(PluginsTestBaseCase):
def test_add_edit_plugin(self):
from cms.test_utils.project.mti_pluginapp.models import TestPluginBetaModel
diff --git a/cms/tests/po.py b/cms/tests/test_po.py
similarity index 100%
rename from cms/tests/po.py
rename to cms/tests/test_po.py
diff --git a/cms/tests/publisher.py b/cms/tests/test_publisher.py
similarity index 100%
rename from cms/tests/publisher.py
rename to cms/tests/test_publisher.py
diff --git a/cms/tests/rendering.py b/cms/tests/test_rendering.py
similarity index 99%
rename from cms/tests/rendering.py
rename to cms/tests/test_rendering.py
index d3f706c3bcf..57cc548689c 100644
--- a/cms/tests/rendering.py
+++ b/cms/tests/test_rendering.py
@@ -155,8 +155,8 @@ def test_details_view(self):
self.assertEqual(r, u'|' + self.test_data['text_main'] + u'|' + self.test_data['text_sub'] + u'|')
@override_settings(
- CMS_PLUGIN_PROCESSORS=('cms.tests.rendering.sample_plugin_processor',),
- CMS_PLUGIN_CONTEXT_PROCESSORS=('cms.tests.rendering.sample_plugin_context_processor',),
+ CMS_PLUGIN_PROCESSORS=('cms.tests.test_rendering.sample_plugin_processor',),
+ CMS_PLUGIN_CONTEXT_PROCESSORS=('cms.tests.test_rendering.sample_plugin_context_processor',),
)
def test_processors(self):
"""
diff --git a/cms/tests/reversion_tests.py b/cms/tests/test_reversion_tests.py
similarity index 100%
rename from cms/tests/reversion_tests.py
rename to cms/tests/test_reversion_tests.py
diff --git a/cms/tests/security.py b/cms/tests/test_security.py
similarity index 100%
rename from cms/tests/security.py
rename to cms/tests/test_security.py
diff --git a/cms/tests/settings.py b/cms/tests/test_settings.py
similarity index 100%
rename from cms/tests/settings.py
rename to cms/tests/test_settings.py
diff --git a/cms/tests/signals.py b/cms/tests/test_signals.py
similarity index 100%
rename from cms/tests/signals.py
rename to cms/tests/test_signals.py
diff --git a/cms/tests/site.py b/cms/tests/test_site.py
similarity index 100%
rename from cms/tests/site.py
rename to cms/tests/test_site.py
diff --git a/cms/tests/sitemap.py b/cms/tests/test_sitemap.py
similarity index 100%
rename from cms/tests/sitemap.py
rename to cms/tests/test_sitemap.py
diff --git a/cms/tests/static_analysis.py b/cms/tests/test_static_analysis.py
similarity index 51%
rename from cms/tests/static_analysis.py
rename to cms/tests/test_static_analysis.py
index 249896effa4..4fd2f6f0137 100644
--- a/cms/tests/static_analysis.py
+++ b/cms/tests/test_static_analysis.py
@@ -1,4 +1,10 @@
-from unittest import TestCase
+import sys
+
+if sys.version_info[0] == 2 and sys.version_info[1] == 6:
+ from django.test.testcases import TestCase
+else:
+ from unittest import TestCase
+
from cms.test_utils.util.static_analysis import pyflakes
@@ -9,4 +15,5 @@ class AboveStaticAnalysisCodeTest(TestCase):
def test_pyflakes(self):
import cms
import menus
- self.assertEqual(pyflakes((cms, menus)), 0)
+ errors, message = pyflakes((cms, menus))
+ self.assertEqual(errors, 0, message)
diff --git a/cms/tests/static_placeholder.py b/cms/tests/test_static_placeholder.py
similarity index 99%
rename from cms/tests/static_placeholder.py
rename to cms/tests/test_static_placeholder.py
index f9e53517add..dbc8dc78392 100644
--- a/cms/tests/static_placeholder.py
+++ b/cms/tests/test_static_placeholder.py
@@ -10,7 +10,7 @@
from cms.api import add_plugin
from cms.constants import PLUGIN_MOVE_ACTION, PLUGIN_COPY_ACTION
from cms.models import StaticPlaceholder, Placeholder, CMSPlugin
-from cms.tests.plugins import PluginsTestBaseCase
+from cms.tests.test_plugins import PluginsTestBaseCase
from cms.utils.urlutils import admin_reverse
diff --git a/cms/tests/staticfiles.py b/cms/tests/test_staticfiles.py
similarity index 100%
rename from cms/tests/staticfiles.py
rename to cms/tests/test_staticfiles.py
diff --git a/cms/tests/templates.py b/cms/tests/test_templates.py
similarity index 100%
rename from cms/tests/templates.py
rename to cms/tests/test_templates.py
diff --git a/cms/tests/templatetags.py b/cms/tests/test_templatetags.py
similarity index 100%
rename from cms/tests/templatetags.py
rename to cms/tests/test_templatetags.py
diff --git a/cms/tests/toolbar.py b/cms/tests/test_toolbar.py
similarity index 99%
rename from cms/tests/toolbar.py
rename to cms/tests/test_toolbar.py
index 72e4e2e37a6..a01efc84a6a 100644
--- a/cms/tests/toolbar.py
+++ b/cms/tests/test_toolbar.py
@@ -27,7 +27,8 @@
detail_view_multi,
detail_view_multi_unfiltered, ClassDetail)
from cms.test_utils.testcases import (CMSTestCase,
- URL_CMS_PAGE_ADD, URL_CMS_PAGE_CHANGE)
+ URL_CMS_PAGE_ADD, URL_CMS_PAGE_CHANGE,
+ ClearURLs)
from cms.test_utils.util.context_managers import UserLoginContext
from cms.toolbar.items import (ToolbarAPIMixin, LinkItem, ItemSearchResult,
Break, SubMenu, AjaxItem)
@@ -92,33 +93,37 @@ def _fake_logentry(self, instance_id, user, text, model=Page):
@override_settings(ROOT_URLCONF='cms.test_utils.project.nonroot_urls')
-class ToolbarMiddlewareTest(ToolbarTestBase):
-
+class ToolbarMiddlewareTest(ClearURLs, ToolbarTestBase):
+ @override_settings(CMS_APP_NAME=None)
+ @override_settings(CMS_TOOLBAR_HIDE=False)
def test_no_app_setted_show_toolbar_in_non_cms_urls(self):
request = self.get_page_request(None, self.get_anon(), '/')
- self.assertTrue(hasattr(request,'toolbar'))
+ self.assertTrue(hasattr(request, 'toolbar'))
+ @override_settings(CMS_APP_NAME=None)
+ @override_settings(CMS_TOOLBAR_HIDE=False)
def test_no_app_setted_show_toolbar_in_cms_urls(self):
- page = create_page('foo','col_two.html','en',published=True)
+ page = create_page('foo', 'col_two.html', 'en', published=True)
request = self.get_page_request(page, self.get_anon())
- self.assertTrue(hasattr(request,'toolbar'))
+ self.assertTrue(hasattr(request, 'toolbar'))
@override_settings(CMS_APP_NAME='cms')
+ @override_settings(CMS_TOOLBAR_HIDE=False)
def test_app_setted_hide_toolbar_in_non_cms_urls_toolbar_hide_unsetted(self):
request = self.get_page_request(None, self.get_anon(), '/')
- self.assertTrue(hasattr(request,'toolbar'))
+ self.assertTrue(hasattr(request, 'toolbar'))
@override_settings(CMS_APP_NAME='cms')
@override_settings(CMS_TOOLBAR_HIDE=True)
def test_app_setted_hide_toolbar_in_non_cms_urls(self):
request = self.get_page_request(None, self.get_anon(), '/')
- self.assertFalse(hasattr(request,'toolbar'))
+ self.assertFalse(hasattr(request, 'toolbar'))
@override_settings(CMS_APP_NAME='cms')
def test_app_setted_show_toolbar_in_cms_urls(self):
- page = create_page('foo','col_two.html','en',published=True)
+ page = create_page('foo', 'col_two.html', 'en', published=True)
request = self.get_page_request(page, self.get_anon())
- self.assertTrue(hasattr(request,'toolbar'))
+ self.assertTrue(hasattr(request, 'toolbar'))
@override_settings(CMS_PERMISSION=False)
diff --git a/cms/tests/toolbar_pool.py b/cms/tests/test_toolbar_pool.py
similarity index 61%
rename from cms/tests/toolbar_pool.py
rename to cms/tests/test_toolbar_pool.py
index ae8c96f365c..c4e51ae35e0 100644
--- a/cms/tests/toolbar_pool.py
+++ b/cms/tests/test_toolbar_pool.py
@@ -14,47 +14,48 @@ class TestToolbar(CMSToolbar):
class ToolbarPoolTests(CMSTestCase):
-
- def setUp(self):
- self.pool = ToolbarPool()
-
def test_register(self):
- self.pool.register(TestToolbar)
- self.pool.register(CMSToolbar)
- self.assertEqual(self.pool.toolbars, {
+ pool = ToolbarPool()
+ pool.register(TestToolbar)
+ pool.register(CMSToolbar)
+ self.assertEqual(pool.toolbars, {
'cms.toolbar_base.CMSToolbar': CMSToolbar,
- 'cms.tests.toolbar_pool.TestToolbar': TestToolbar})
+ 'cms.tests.test_toolbar_pool.TestToolbar': TestToolbar})
self.assertRaises(ToolbarAlreadyRegistered,
- self.pool.register, TestToolbar)
+ pool.register, TestToolbar)
def test_register_type(self):
- self.assertRaises(ImproperlyConfigured, self.pool.register, str)
- self.assertRaises(ImproperlyConfigured, self.pool.register, object)
+ pool = ToolbarPool()
+ self.assertRaises(ImproperlyConfigured, pool.register, str)
+ self.assertRaises(ImproperlyConfigured, pool.register, object)
def test_register_order(self):
- self.pool.register(TestToolbar)
- self.pool.register(CMSToolbar)
+ pool = ToolbarPool()
+ pool.register(TestToolbar)
+ pool.register(CMSToolbar)
test_toolbar = SortedDict()
- test_toolbar['cms.tests.toolbar_pool.TestToolbar'] = TestToolbar
+ test_toolbar['cms.tests.test_toolbar_pool.TestToolbar'] = TestToolbar
test_toolbar['cms.toolbar_base.CMSToolbar'] = CMSToolbar
- self.assertEqual(list(test_toolbar.keys()), list(self.pool.toolbars.keys()))
+ self.assertEqual(list(test_toolbar.keys()), list(pool.toolbars.keys()))
def test_unregister(self):
- self.pool.register(TestToolbar)
- self.pool.unregister(TestToolbar)
- self.assertEqual(self.pool.toolbars, {})
+ pool = ToolbarPool()
+ pool.register(TestToolbar)
+ pool.unregister(TestToolbar)
+ self.assertEqual(pool.toolbars, {})
self.assertRaises(ToolbarNotRegistered,
- self.pool.unregister, TestToolbar)
+ pool.unregister, TestToolbar)
def test_settings(self):
+ pool = ToolbarPool()
toolbars = toolbar_pool.toolbars
toolbar_pool.clear()
with self.settings(CMS_TOOLBARS=['cms.cms_toolbars.BasicToolbar', 'cms.cms_toolbars.PlaceholderToolbar']):
toolbar_pool.register(TestToolbar)
- self.assertEqual(len(list(self.pool.get_toolbars().keys())), 2)
+ self.assertEqual(len(list(pool.get_toolbars().keys())), 2)
api.create_page("home", "simple.html", "en", published=True)
with self.login_user_context(self.get_superuser()):
response = self.client.get("/en/?%s" % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON'))
diff --git a/cms/tests/urlutils.py b/cms/tests/test_urlutils.py
similarity index 100%
rename from cms/tests/urlutils.py
rename to cms/tests/test_urlutils.py
diff --git a/cms/tests/views.py b/cms/tests/test_views.py
similarity index 99%
rename from cms/tests/views.py
rename to cms/tests/test_views.py
index 0713c2c6125..ba14ea03d7f 100644
--- a/cms/tests/views.py
+++ b/cms/tests/test_views.py
@@ -15,7 +15,7 @@
from cms.apphook_pool import apphook_pool
from cms.models import PagePermission, UserSettings, Placeholder
from cms.page_rendering import _handle_no_page
-from cms.test_utils.testcases import CMSTestCase
+from cms.test_utils.testcases import CMSTestCase, ClearURLs
from cms.test_utils.util.fuzzy_int import FuzzyInt
from cms.utils.compat import DJANGO_1_7
from cms.utils.conf import get_cms_setting
@@ -192,7 +192,7 @@ def test_toolbar_switch_urls(self):
@override_settings(ROOT_URLCONF='cms.test_utils.project.urls')
-class ContextTests(CMSTestCase):
+class ContextTests(ClearURLs, CMSTestCase):
def test_context_current_page(self):
"""
diff --git a/cms/tests/widgets.py b/cms/tests/test_widgets.py
similarity index 100%
rename from cms/tests/widgets.py
rename to cms/tests/test_widgets.py
diff --git a/cms/toolbar_pool.py b/cms/toolbar_pool.py
index c5ff2014ab8..6551e95362a 100644
--- a/cms/toolbar_pool.py
+++ b/cms/toolbar_pool.py
@@ -37,11 +37,8 @@ def clear(self):
self._discovered = False
def register(self, toolbar):
- import os
- import inspect
import warnings
- source_file = os.path.basename(inspect.stack()[1][1])
- if source_file == 'cms_toolbar.py':
+ if toolbar.__module__.split('.')[-1] == 'cms_toolbar':
warnings.warn('cms_toolbar.py filename is deprecated, '
'and it will be removed in version 3.4; '
'please rename it to cms_toolbar.py', DeprecationWarning)
diff --git a/cms/utils/conf.py b/cms/utils/conf.py
index 397e5ed1b45..74629dec199 100644
--- a/cms/utils/conf.py
+++ b/cms/utils/conf.py
@@ -61,8 +61,8 @@ def wrapper():
'TOOLBAR_URL__BUILD': 'build',
'TOOLBAR_URL__DISABLE': 'toolbar_off',
'ADMIN_NAMESPACE': 'admin',
- 'APP_NAME':None,
- 'TOOLBAR_HIDE':False
+ 'APP_NAME': None,
+ 'TOOLBAR_HIDE': False
}
diff --git a/cms/utils/permissions.py b/cms/utils/permissions.py
index 233d163af84..c0c06b30ef9 100644
--- a/cms/utils/permissions.py
+++ b/cms/utils/permissions.py
@@ -11,7 +11,6 @@
from cms.exceptions import NoPermissionsException
from cms.models import (Page, PagePermission, GlobalPagePermission,
MASK_PAGE, MASK_CHILDREN, MASK_DESCENDANTS)
-from cms.plugin_pool import plugin_pool
from cms.utils.conf import get_cms_setting
@@ -420,6 +419,7 @@ def has_plugin_permission(user, plugin_type, permission_type):
the action defined in permission_type
permission_type should be 'add', 'change' or 'delete'.
"""
+ from cms.plugin_pool import plugin_pool
plugin_class = plugin_pool.get_plugin(plugin_type)
plugin_model = plugin_class.model
plugin_opts = plugin_model._meta
diff --git a/develop.py b/develop.py
deleted file mode 100755
index 3fdaf83d2a1..00000000000
--- a/develop.py
+++ /dev/null
@@ -1,437 +0,0 @@
-#!/usr/bin/env python
-from __future__ import print_function, with_statement
-
-import contextlib
-import multiprocessing
-import pkgutil
-import pyclbr
-import subprocess
-import os
-import sys
-import warnings
-
-from django.core.exceptions import DjangoRuntimeWarning
-from django.core.exceptions import ImproperlyConfigured
-from django.core.management import call_command, CommandError
-from django.utils import autoreload
-from django.utils.encoding import force_text
-
-from docopt import docopt
-
-import cms
-from cms.test_utils.cli import configure
-from cms.test_utils.util import static_analysis
-from cms.test_utils.tmpdir import temp_dir
-from cms.utils.compat import DJANGO_1_6
-import menus
-
-__doc__ = '''django CMS development helper script.
-
-To use a different database, set the DATABASE_URL environment variable to a
-dj-database-url compatible value. The AUTH_USER_MODEL environment variable can
-be used to change the user model in the same manner as the --user option.
-
-Usage:
- develop.py test [--parallel | --failfast] [--migrate] [--user=]
- [...] [--xvfb]
- develop.py timed test [test-label...] [--xvfb]
- develop.py isolated test [...] [--parallel] [--migrate]
- [--xvfb]
- develop.py server [--port=] [--bind=] [--migrate]
- [--user=] [ ]
- develop.py shell
- develop.py compilemessages
- develop.py makemessages
- develop.py makemigrations [--merge]
- develop.py squashmigrations
- develop.py pyflakes
- develop.py authors
-
-Options:
- -h --help Show this screen.
- --version Show version.
- --parallel Run tests in parallel.
- --migrate Use south migrations in test or server command.
- --merge Merge migrations
- --failfast Stop tests on first failure (only if not --parallel).
- --port= Port to listen on [default: 8000].
- --bind= Interface to bind to [default: 127.0.0.1].
- --user= Specify which user model to run tests with (if other
- than auth.User).
- --xvfb Use a virtual X framebuffer for frontend testing,
- requires xvfbwrapper to be installed.
-'''
-
-
-def server(bind='127.0.0.1', port=8000, migrate_cmd=False, app_name=None, migration=None):
- if os.environ.get("RUN_MAIN") != "true":
- from django.contrib.auth import get_user_model # must be imported lazily
- if DJANGO_1_6:
- from south.management.commands import syncdb, migrate
- if migrate_cmd:
- syncdb.Command().handle_noargs(interactive=False, verbosity=1,
- database='default')
- if app_name:
- migrate.Command().handle(interactive=False, verbosity=1, app=app_name,
- target=migration)
- else:
- migrate.Command().handle(interactive=False, verbosity=1)
- else:
- syncdb.Command().handle_noargs(interactive=False, verbosity=1,
- database='default',
- migrate=False, migrate_all=True)
- migrate.Command().handle(interactive=False, verbosity=1,
- fake=True)
- else:
- if app_name:
- call_command("migrate", app_name, migration, database='default')
- else:
- call_command("migrate", database='default')
- User = get_user_model()
- if not User.objects.filter(is_superuser=True).exists():
- usr = User()
-
- if(User.USERNAME_FIELD != 'email'):
- setattr(usr, User.USERNAME_FIELD, 'admin')
-
- usr.email = 'admin@admin.com'
- usr.set_password('admin')
- usr.is_superuser = True
- usr.is_staff = True
- usr.is_active = True
- usr.save()
- print('')
- print("A admin user (username: admin, password: admin) "
- "has been created.")
- print('')
- from django.contrib.staticfiles.management.commands import runserver
- rs = runserver.Command()
- try:
- from django.core.management.base import OutputWrapper
- rs.stdout = OutputWrapper(sys.stdout)
- rs.stderr = OutputWrapper(sys.stderr)
- except ImportError:
- rs.stdout = sys.stdout
- rs.stderr = sys.stderr
- rs.use_ipv6 = False
- rs._raw_ipv6 = False
- rs.addr = bind
- rs.port = port
- autoreload.main(rs.inner_run, (), {
- 'addrport': '%s:%s' % (bind, port),
- 'insecure_serving': True,
- 'use_threading': True
- })
-
-
-def _split(itr, num):
- split = []
- size = int(len(itr) / num)
- for index in range(num):
- split.append(itr[size * index:size * (index + 1)])
- return split
-
-
-def _get_test_labels():
- test_labels = []
- if DJANGO_1_6:
- for module in [name for _, name, _ in pkgutil.iter_modules(
- [os.path.join("cms", "tests")])]:
- clsmembers = pyclbr.readmodule("cms.tests.%s" % module)
- for clsname, cls in clsmembers.items():
- for method, _ in cls.methods.items():
- if method.startswith('test_'):
- test_labels.append('cms.%s.%s' % (clsname, method))
- else:
- for module in [name for _, name, _ in pkgutil.iter_modules(
- [os.path.join("cms", "tests")])]:
- clsmembers = pyclbr.readmodule("cms.tests.%s" % module)
- for clsname, cls in clsmembers.items():
- for method, _ in cls.methods.items():
- if method.startswith('test_'):
- test_labels.append('cms.tests.%s.%s' % (clsname, method))
- test_labels = sorted(test_labels)
- return test_labels
-
-
-def _test_run_worker(test_labels, failfast=False, test_runner=None):
- warnings.filterwarnings(
- 'error', r"DateTimeField received a naive datetime",
- RuntimeWarning, r'django\.db\.models\.fields')
- from django.conf import settings
- from django.test.utils import get_runner
- if not test_runner:
- if DJANGO_1_6:
- test_runner = 'django.test.simple.DjangoTestSuiteRunner'
- else:
- test_runner = 'django.test.runner.DiscoverRunner'
- if not test_labels:
- test_labels = _get_test_labels()
- settings.TEST_RUNNER = test_runner
- TestRunner = get_runner(settings)
- test_runner = TestRunner(verbosity=1, pattern="*.py", top_level='cms',
- interactive=False, failfast=failfast)
- failures = test_runner.run_tests(test_labels)
- return failures
-
-
-def _test_in_subprocess(test_labels):
- return subprocess.call(['python', 'develop.py', 'test'] + test_labels)
-
-
-def isolated(test_labels, parallel=False):
- test_labels = test_labels or _get_test_labels()
- if parallel:
- pool = multiprocessing.Pool()
- mapper = pool.map
- else:
- mapper = map
- results = mapper(
- _test_in_subprocess,
- ([test_label] for test_label in test_labels)
- )
- failures = [test_label for test_label, return_code in zip(
- test_labels, results) if return_code != 0]
- return failures
-
-
-def timed(test_labels):
- return _test_run_worker(
- test_labels,
- test_runner='cms.test_utils.runners.TimedTestRunner'
- )
-
-
-def test(test_labels, parallel=False, failfast=False):
- test_labels = test_labels or _get_test_labels()
- if parallel:
- worker_tests = _split(test_labels, multiprocessing.cpu_count())
-
- pool = multiprocessing.Pool()
- failures = sum(pool.map(_test_run_worker, worker_tests))
- return failures
- else:
- return _test_run_worker(test_labels, failfast)
-
-
-def compilemessages():
- from django.core.management import call_command
- os.chdir('cms')
- call_command('compilemessages', all=True)
-
-
-def makemessages():
- from django.core.management import call_command
- os.chdir('cms')
- call_command('makemessages', locale=('en',))
- call_command('makemessages', locale=('en',), domain='djangojs')
-
-
-def shell():
- from django.core.management import call_command
- call_command('shell')
-
-
-def makemigrations(migrate_plugins=True, merge=False, squash=False):
- applications = [
- # core applications
- 'cms', 'menus',
- # testing applications
- 'meta', 'manytomany_rel', 'fileapp', 'placeholderapp', 'sampleapp',
- 'fakemlng', 'one_thing', 'extensionapp', 'objectpermissionsapp',
- 'bunch_of_plugins', 'mti_pluginapp',
- ]
- if os.environ.get("AUTH_USER_MODEL") == "emailuserapp.EmailUser":
- applications.append('emailuserapp')
- if os.environ.get("AUTH_USER_MODEL") == "customuserapp.User":
- applications.append('customuserapp')
- if migrate_plugins:
- applications.extend([
- # official plugins
- 'djangocms_inherit', 'djangocms_googlemap', 'djangocms_column',
- 'djangocms_style', 'djangocms_link', 'djangocms_file',
- 'djangocms_text_ckeditor', 'djangocms_picture', 'djangocms_teaser',
- 'djangocms_file', 'djangocms_flash', 'djangocms_video',
- ])
- if DJANGO_1_6:
- from south.exceptions import NoMigrations
- from south.migration import Migrations
-
- if merge:
- raise DjangoRuntimeWarning(
- u'Option not implemented for Django 1.6')
- for application in applications:
- try:
- Migrations(application)
- except NoMigrations:
- print('ATTENTION: No migrations found for {0}, creating '
- 'initial migrations.'.format(application))
- try:
- call_command('schemamigration', application, initial=True)
- except SystemExit:
- pass
- except ImproperlyConfigured:
- print('WARNING: The app: {0} could not be found.'.format(
- application
- ))
- else:
- try:
- call_command('schemamigration', application, auto=True)
- except SystemExit:
- pass
- else:
- call_command('makemigrations', *applications, merge=merge)
-
-
-def squashmigrations(application, migration):
- if DJANGO_1_6:
- raise CommandError(u'Command not implemented for Django 1.6')
- else:
- call_command('squashmigrations', application, migration)
-
-
-def generate_authors():
- print("Generating AUTHORS")
-
- # Get our list of authors
- print("Collecting author names")
- r = subprocess.Popen(
- ["git", "log", "--use-mailmap", "--format=%aN"],
- stdout=subprocess.PIPE
- )
- seen_authors = []
- authors = []
- with open('AUTHORS', 'r') as f:
- for line in f.readlines():
- if line.startswith("*"):
- author = force_text(line).strip("* \n")
- if author.lower() not in seen_authors:
- seen_authors.append(author.lower())
- authors.append(author)
- for author in r.stdout.readlines():
- author = force_text(author).strip()
- if author.lower() not in seen_authors:
- seen_authors.append(author.lower())
- authors.append(author)
-
- # Sort our list of Authors by their case insensitive name
- authors = sorted(authors, key=lambda x: x.lower())
-
- # Write our authors to the AUTHORS file
- print(u"Authors (%s):\n\n\n* %s" % (len(authors), u"\n* ".join(authors)))
-
-
-def main():
- args = docopt(__doc__, version=cms.__version__)
-
- if args['pyflakes']:
- return static_analysis.pyflakes((cms, menus))
-
- if args['authors']:
- return generate_authors()
-
- # configure django
- warnings.filterwarnings(
- 'error', r"DateTimeField received a naive datetime",
- RuntimeWarning, r'django\.db\.models\.fields')
-
- default_name = ':memory:' if args['test'] else 'local.sqlite'
-
- db_url = os.environ.get(
- "DATABASE_URL",
- "sqlite://localhost/%s" % default_name
- )
- migrate = (args.get('--migrate', False) or
- args.get('makemigrations', False) or
- args.get('squashmigrations', False))
-
- with temp_dir() as STATIC_ROOT:
- with temp_dir() as MEDIA_ROOT:
- configs = {
- 'db_url': db_url,
- 'ROOT_URLCONF': 'cms.test_utils.project.urls',
- 'STATIC_ROOT': STATIC_ROOT,
- 'MEDIA_ROOT': MEDIA_ROOT,
- 'USE_TZ': True,
- 'TESTS_MIGRATE': migrate,
- }
-
- if args['test']:
- configs['SESSION_ENGINE'] = "django.contrib.sessions.backends.cache"
-
- # Command line option takes precedent over environment variable
- auth_user_model = args['--user']
-
- if not auth_user_model:
- auth_user_model = os.environ.get("AUTH_USER_MODEL", None)
-
- if auth_user_model:
- configs['AUTH_USER_MODEL'] = auth_user_model
-
- configure(**configs)
-
- # run
- if args['test']:
- # make "Address already in use" errors less likely, see Django
- # docs for more details on this env variable.
- os.environ.setdefault(
- 'DJANGO_LIVE_TEST_SERVER_ADDRESS',
- 'localhost:8000-9000'
- )
- if args['--xvfb']:
- import xvfbwrapper
- context = xvfbwrapper.Xvfb(width=1280, height=720)
- else:
- @contextlib.contextmanager
- def null_context():
- yield
- context = null_context()
-
- with context:
- if args['isolated']:
- failures = isolated(
- args[''], args['--parallel']
- )
- print()
- print("Failed tests")
- print("============")
- if failures:
- for failure in failures:
- print(" - %s" % failure)
- else:
- print(" None")
- num_failures = len(failures)
- elif args['timed']:
- num_failures = timed(args[''])
- else:
- num_failures = test(
- args[''],
- args['--parallel'],
- args['--failfast']
- )
- sys.exit(num_failures)
- elif args['server']:
- server(
- args['--bind'],
- args['--port'],
- args.get('--migrate', True),
- args.get('', None),
- args.get('', None)
- )
- elif args['shell']:
- shell()
- elif args['compilemessages']:
- compilemessages()
- elif args['makemessages']:
- makemessages()
- elif args['makemigrations']:
- makemigrations(merge=args['--merge'])
- elif args['squashmigrations']:
- squashmigrations(
- args[''],
- args['']
- )
-
-
-if __name__ == '__main__':
- main()
diff --git a/docs/contributing/testing.rst b/docs/contributing/testing.rst
index 37a79ab5a8e..25ef845c217 100644
--- a/docs/contributing/testing.rst
+++ b/docs/contributing/testing.rst
@@ -48,7 +48,7 @@ There's more than one way to do this, but here's one to help you get started::
# note that you must be in the django-cms directory when you do this,
# otherwise you'll get "Template not found" errors
cd django-cms
- python develop.py test
+ python manage.py test
It can take a few minutes to run. Note that the selenium tests included in the
@@ -97,120 +97,30 @@ and it should then run without errors.
Advanced testing options
========================
-``develop.py`` is the django CMS development helper script.
+Run ``manage.py test --help`` for full list of advanced options.
-To use a different database, set the ``DATABASE_URL`` environment variable to a
-dj-database-url compatible value.
+Use ``--parallel`` to distribute the test cases across your CPU cores.
-.. program:: develop.py
+Use ``--failed`` to only run the tests that failed during the last run.
-.. option:: -h, --help
+Use ``--retest`` to run the tests using the same configuration as the last run.
- Show help.
+Use ``--vanilla`` to bypass the advanced testing system and use the built-in
+Django test command.
-.. option:: --version
- Show CMS version.
+Using Xvfb for headless frontend testing
+----------------------------------------
-.. option:: --user
+On Linux systems with X you can use Xvfb (X virtual frame buffer) to run
+frontend tests headless (without the browser window actually showing). To do
+so, it's recommended to use the ``xvfb-run`` script to run tests.
- Specifies a custom user model to use for testing, the shell, or the server. The name must be in the format ., and the custom app must reside in the cms.test_utils.projects module.
+.. important::
-
-``develop.py test``
--------------------
-
-.. program:: develop.py test
-
-Runs the test suite. Optionally takes test labels as arguments to limit the tests which should be run.
-Test labels should be in the same format as used in ``manage.py test``.
-
-.. option:: --xvfb
-
- Use a virtual X framebuffer for frontend testing, requires `xvfbwrapper `_ to be installed.
-
- With this option you won't need a physical display.
-
-.. option:: --parallel
-
- Runs tests in parallel, using one worker process per available CPU core.
-
- Cannot be used together with :option:`develop.py test --failfast`.
-
- .. note::
-
- The output of the worker processes will be shown interleaved, which means that you'll get the
- results from each worker process individually, which might cause confusing output at the end of
- the test run.
-
-.. option:: --failfast
-
- Stop running tests on the first failure or error.
-
-
-``develop.py timed test``
--------------------------
-
-.. program:: develop.py timed test
-
-Run the test suite and print the ten slowest tests. Optionally takes test labels as arguments to limit the tests which should be run.
-Test labels should be in the same format as used in ``manage.py test``.
-
-
-``develop.py isolated test``
-----------------------------
-
-.. program:: develop.py isolated test
-
-Runs each test in the test suite in a new process, thus making sure that tests don't leak state. This takes a
-very long time to run. Optionally takes test labels as arguments to limit the tests which should be run.
-Test labels should be in the same format as used in ``manage.py test``.
-
-.. option:: --parallel
-
- Same as :option:`develop.py test --parallel`.
-
-
-``develop.py server``
----------------------
-
-.. program:: develop.py server
-
-Run a server locally for testing. This is similar to ``manage.py runserver``.
-
-.. option:: --port
-
- Port to bind to. Defaults to 8000.
-
-.. option:: --bind
-
- Interface to bind to. Defaults to 127.0.0.1.
-
-.. option:: --migrate
-
- Use migrations instead of plain syncdb.
-
-.. option:: application-name, migration-number
-
- Options to specify a single migration to migrate to. When using Django 1.6
- it only works if --migrate option is specified.
-
-
-
-``develop.py shell``
---------------------
-
-.. program:: develop.py shell
-
-Opens a Django shell. This is similar to ``manage.py shell``.
-
-
-``develop.py compilemessages``
-------------------------------
-
-.. program:: develop.py compilemessages
-
-Compiles the po files to mo files. This is similar to ``manage.py compilemessages``.
+ The frontend tests have a minimum screen size to run successfully. You must
+ set the screen size of the virtual frame buffer to at least 1280x720x8.
+ You may do so using ``xvfb-run -s"-screen 0 1280x720x8" ...``.
*************
diff --git a/manage.py b/manage.py
new file mode 100644
index 00000000000..875ad3fb621
--- /dev/null
+++ b/manage.py
@@ -0,0 +1,355 @@
+# -*- coding: utf-8 -*-
+import os
+
+import app_manage
+
+from cms.utils.compat import DJANGO_1_6, DJANGO_1_7
+
+gettext = lambda s: s
+
+
+if __name__ == '__main__':
+ os.environ.setdefault(
+ 'DJANGO_LIVE_TEST_SERVER_ADDRESS',
+ 'localhost:8000-9000'
+ )
+ PROJECT_PATH = os.path.abspath(
+ os.path.join(os.path.dirname(__file__), 'cms', 'test_utils')
+ )
+
+ INSTALLED_APPS = [
+ 'debug_toolbar',
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'djangocms_admin_style',
+ 'django.contrib.admin',
+ 'django.contrib.sites',
+ 'django.contrib.staticfiles',
+ 'django.contrib.messages',
+ 'treebeard',
+ 'cms',
+ 'menus',
+ 'djangocms_text_ckeditor',
+ 'djangocms_column',
+ 'djangocms_picture',
+ 'djangocms_file',
+ 'djangocms_flash',
+ 'djangocms_googlemap',
+ 'djangocms_teaser',
+ 'djangocms_video',
+ 'djangocms_inherit',
+ 'djangocms_style',
+ 'djangocms_link',
+ 'cms.test_utils.project.sampleapp',
+ 'cms.test_utils.project.placeholderapp',
+ 'cms.test_utils.project.pluginapp.plugins.manytomany_rel',
+ 'cms.test_utils.project.pluginapp.plugins.extra_context',
+ 'cms.test_utils.project.pluginapp.plugins.meta',
+ 'cms.test_utils.project.pluginapp.plugins.one_thing',
+ 'cms.test_utils.project.fakemlng',
+ 'cms.test_utils.project.fileapp',
+ 'cms.test_utils.project.objectpermissionsapp',
+ 'cms.test_utils.project.bunch_of_plugins',
+ 'cms.test_utils.project.extensionapp',
+ 'cms.test_utils.project.mti_pluginapp',
+ 'reversion',
+ 'sekizai',
+ 'hvad',
+ 'better_test',
+ ]
+
+ dynamic_configs = {}
+
+ if DJANGO_1_7:
+ dynamic_configs.update(dict(
+ TEMPLATE_CONTEXT_PROCESSORS=[
+ "django.contrib.auth.context_processors.auth",
+ 'django.contrib.messages.context_processors.messages',
+ "django.core.context_processors.i18n",
+ "django.core.context_processors.debug",
+ "django.core.context_processors.request",
+ "django.core.context_processors.media",
+ 'django.core.context_processors.csrf',
+ "cms.context_processors.cms_settings",
+ "sekizai.context_processors.sekizai",
+ "django.core.context_processors.static",
+ ],
+ TEMPLATE_LOADERS=(
+ 'django.template.loaders.filesystem.Loader',
+ 'django.template.loaders.app_directories.Loader',
+ 'django.template.loaders.eggs.Loader',
+ ),
+ TEMPLATE_DIRS=[
+ os.path.abspath(os.path.join(PROJECT_PATH, 'project', 'templates'))
+ ],
+ TEMPLATE_DEBUG=True
+ ))
+ else:
+ dynamic_configs['TEMPLATES'] = [
+ {
+ 'NAME': 'django',
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'APP_DIRS': True,
+ 'DIRS': [os.path.abspath(os.path.join(PROJECT_PATH, 'project', 'templates'))],
+ 'OPTIONS': {
+ 'context_processors': [
+ "django.contrib.auth.context_processors.auth",
+ 'django.contrib.messages.context_processors.messages',
+ "django.template.context_processors.i18n",
+ "django.template.context_processors.debug",
+ "django.template.context_processors.request",
+ "django.template.context_processors.media",
+ 'django.template.context_processors.csrf',
+ "cms.context_processors.cms_settings",
+ "sekizai.context_processors.sekizai",
+ "django.template.context_processors.static",
+ ],
+ 'debug': True,
+ }
+ }
+ ]
+
+ if DJANGO_1_6:
+ # South overrides the test command, thus insert it before better_test
+ INSTALLED_APPS.insert(0, 'south')
+ dynamic_configs['SOUTH_MIGRATION_MODULES'] = {
+ 'cms': 'cms.south_migrations',
+ 'menus': 'menus.south_migrations',
+ 'djangocms_column': 'djangocms_column.migrations',
+ 'djangocms_file': 'djangocms_file.migrations',
+ 'djangocms_flash': 'djangocms_flash.migrations',
+ 'djangocms_googlemap': 'djangocms_googlemap.migrations',
+ 'djangocms_inherit': 'djangocms_inherit.migrations',
+ 'djangocms_link': 'djangocms_link.migrations',
+ 'djangocms_picture': 'djangocms_picture.migrations',
+ 'djangocms_style': 'djangocms_style.migrations',
+ 'djangocms_teaser': 'djangocms_teaser.migrations',
+ 'djangocms_text_ckeditor': 'djangocms_text_ckeditor.south_migrations',
+ 'djangocms_video': 'djangocms_video.migrations',
+ 'meta': 'cms.test_utils.project.pluginapp.plugins.meta.south_migrations',
+ 'manytomany_rel': 'cms.test_utils.project.pluginapp.plugins.manytomany_rel.south_migrations',
+ 'fileapp': 'cms.test_utils.project.fileapp.south_migrations',
+ 'placeholderapp': 'cms.test_utils.project.placeholderapp.south_migrations',
+ 'sampleapp': 'cms.test_utils.project.sampleapp.south_migrations',
+ 'emailuserapp': 'cms.test_utils.project.emailuserapp.south_migrations',
+ 'customuserapp': 'cms.test_utils.project.customuserapp.south_migrations',
+ 'fakemlng': 'cms.test_utils.project.fakemlng.south_migrations',
+ 'extra_context': 'cms.test_utils.project.pluginapp.plugins.extra_context.south_migrations',
+ 'one_thing': 'cms.test_utils.project.pluginapp.plugins.one_thing.south_migrations',
+ 'bunch_of_plugins': 'cms.test_utils.project.bunch_of_plugins.south_migrations',
+ 'extensionapp': 'cms.test_utils.project.extensionapp.south_migrations',
+ 'objectpermissionsapp': 'cms.test_utils.project.objectpermissionsapp.south_migrations',
+ 'mti_pluginapp': 'cms.test_utils.project.mti_pluginapp.south_migrations',
+ }
+ else:
+ dynamic_configs['MIGRATION_MODULES'] = {
+ 'djangocms_column': 'djangocms_column.migrations_django',
+ 'djangocms_file': 'djangocms_file.migrations_django',
+ 'djangocms_flash': 'djangocms_flash.migrations_django',
+ 'djangocms_googlemap': 'djangocms_googlemap.migrations_django',
+ 'djangocms_inherit': 'djangocms_inherit.migrations_django',
+ 'djangocms_link': 'djangocms_link.migrations_django',
+ 'djangocms_picture': 'djangocms_picture.migrations_django',
+ 'djangocms_style': 'djangocms_style.migrations_django',
+ 'djangocms_teaser': 'djangocms_teaser.migrations_django',
+ 'djangocms_video': 'djangocms_video.migrations_django',
+ 'meta': 'cms.test_utils.project.pluginapp.plugins.meta.migrations',
+ 'manytomany_rel': 'cms.test_utils.project.pluginapp.plugins.manytomany_rel.migrations',
+ 'fileapp': 'cms.test_utils.project.fileapp.migrations',
+ 'placeholderapp': 'cms.test_utils.project.placeholderapp.migrations',
+ 'sampleapp': 'cms.test_utils.project.sampleapp.migrations',
+ 'emailuserapp': 'cms.test_utils.project.emailuserapp.migrations',
+ 'fakemlng': 'cms.test_utils.project.fakemlng.migrations',
+ 'extra_context': 'cms.test_utils.project.pluginapp.plugins.extra_context.migrations',
+ 'one_thing': 'cms.test_utils.project.pluginapp.plugins.one_thing.migrations',
+ 'bunch_of_plugins': 'cms.test_utils.project.bunch_of_plugins.migrations',
+ 'extensionapp': 'cms.test_utils.project.extensionapp.migrations',
+ 'objectpermissionsapp': 'cms.test_utils.project.objectpermissionsapp.migrations',
+ 'mti_pluginapp': 'cms.test_utils.project.mti_pluginapp.migrations',
+ }
+
+ app_manage.main(
+ ['cms', 'menus'],
+ PROJECT_PATH=PROJECT_PATH,
+ CACHES={
+ 'default': {
+ 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
+ }
+ },
+ SESSION_ENGINE="django.contrib.sessions.backends.cache",
+ CACHE_MIDDLEWARE_ANONYMOUS_ONLY=True,
+ DEBUG=True,
+ DATABASE_SUPPORTS_TRANSACTIONS=True,
+ DATABASES=app_manage.DatabaseConfig(
+ env='DATABASE_URL',
+ arg='--db-url',
+ default='sqlite://localhost/local.sqlite'
+ ),
+ USE_TZ=app_manage.Config(
+ env='USE_TZ',
+ arg=app_manage.Flag('--use-tz'),
+ default=False,
+ ),
+ SITE_ID=1,
+ USE_I18N=True,
+ MEDIA_ROOT=app_manage.TempDir(),
+ STATIC_ROOT=app_manage.TempDir(),
+ CMS_MEDIA_ROOT=app_manage.TempDir(),
+ CMS_MEDIA_URL='/cms-media/',
+ MEDIA_URL='/media/',
+ STATIC_URL='/static/',
+ ADMIN_MEDIA_PREFIX='/static/admin/',
+ EMAIL_BACKEND='django.core.mail.backends.locmem.EmailBackend',
+ MIDDLEWARE_CLASSES=[
+ 'django.middleware.cache.UpdateCacheMiddleware',
+ 'django.middleware.http.ConditionalGetMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.middleware.locale.LocaleMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'cms.middleware.language.LanguageCookieMiddleware',
+ 'cms.middleware.user.CurrentUserMiddleware',
+ 'cms.middleware.page.CurrentPageMiddleware',
+ 'cms.middleware.toolbar.ToolbarMiddleware',
+ 'django.middleware.cache.FetchFromCacheMiddleware',
+ ],
+ INSTALLED_APPS=INSTALLED_APPS,
+ DEBUG_TOOLBAR_PATCH_SETTINGS = False,
+ INTERNAL_IPS = ['127.0.0.1'],
+ AUTHENTICATION_BACKENDS=(
+ 'django.contrib.auth.backends.ModelBackend',
+ 'cms.test_utils.project.objectpermissionsapp.backends.ObjectPermissionBackend',
+ ),
+ LANGUAGE_CODE="en",
+ LANGUAGES=(
+ ('en', gettext('English')),
+ ('fr', gettext('French')),
+ ('de', gettext('German')),
+ ('pt-br', gettext('Brazilian Portuguese')),
+ ('nl', gettext("Dutch")),
+ ('es-mx', u'Español'),
+ ),
+ CMS_LANGUAGES={
+ 1: [
+ {
+ 'code': 'en',
+ 'name': gettext('English'),
+ 'fallbacks': ['fr', 'de'],
+ 'public': True,
+ },
+ {
+ 'code': 'de',
+ 'name': gettext('German'),
+ 'fallbacks': ['fr', 'en'],
+ 'public': True,
+ },
+ {
+ 'code': 'fr',
+ 'name': gettext('French'),
+ 'public': True,
+ },
+ {
+ 'code': 'pt-br',
+ 'name': gettext('Brazilian Portuguese'),
+ 'public': False,
+ },
+ {
+ 'code': 'es-mx',
+ 'name': u'Español',
+ 'public': True,
+ },
+ ],
+ 2: [
+ {
+ 'code': 'de',
+ 'name': gettext('German'),
+ 'fallbacks': ['fr'],
+ 'public': True,
+ },
+ {
+ 'code': 'fr',
+ 'name': gettext('French'),
+ 'public': True,
+ },
+ ],
+ 3: [
+ {
+ 'code': 'nl',
+ 'name': gettext('Dutch'),
+ 'fallbacks': ['de'],
+ 'public': True,
+ },
+ {
+ 'code': 'de',
+ 'name': gettext('German'),
+ 'fallbacks': ['nl'],
+ 'public': False,
+ },
+ ],
+ 'default': {
+ 'hide_untranslated': False,
+ },
+ },
+ CMS_TEMPLATES=(
+ ('col_two.html', gettext('two columns')),
+ ('col_three.html', gettext('three columns')),
+ ('nav_playground.html', gettext('navigation examples')),
+ ('simple.html', 'simple'),
+ ('static.html', 'static placeholders'),
+ ),
+ CMS_PLACEHOLDER_CONF={
+ 'col_sidebar': {
+ 'plugins': ('FilePlugin', 'FlashPlugin', 'LinkPlugin', 'PicturePlugin',
+ 'TextPlugin', 'SnippetPlugin'),
+ 'name': gettext("sidebar column")
+ },
+ 'col_left': {
+ 'plugins': ('FilePlugin', 'FlashPlugin', 'LinkPlugin', 'PicturePlugin',
+ 'TextPlugin', 'SnippetPlugin', 'GoogleMapPlugin', 'MultiColumnPlugin', 'StylePlugin'),
+ 'name': gettext("left column"),
+ 'plugin_modules': {
+ 'LinkPlugin': 'Different Grouper'
+ },
+ 'plugin_labels': {
+ 'LinkPlugin': gettext('Add a link')
+ },
+ },
+ 'col_right': {
+ 'plugins': ('FilePlugin', 'FlashPlugin', 'LinkPlugin', 'PicturePlugin',
+ 'TextPlugin', 'SnippetPlugin', 'GoogleMapPlugin', 'MultiColumnPlugin', 'StylePlugin'),
+ 'name': gettext("right column")
+ },
+ 'extra_context': {
+ "plugins": ('TextPlugin',),
+ "extra_context": {"width": 250},
+ "name": "extra context"
+ },
+ },
+ CMS_PERMISSION=True,
+ CMS_PUBLIC_FOR='all',
+ CMS_CACHE_DURATIONS={
+ 'menus': 0,
+ 'content': 0,
+ 'permissions': 0,
+ },
+ CMS_APPHOOKS=[],
+ CMS_PLUGIN_PROCESSORS=(),
+ CMS_PLUGIN_CONTEXT_PROCESSORS=(),
+ CMS_SITE_CHOICES_CACHE_KEY='CMS:site_choices',
+ CMS_PAGE_CHOICES_CACHE_KEY='CMS:page_choices',
+ SOUTH_TESTS_MIGRATE=False,
+ CMS_NAVIGATION_EXTENDERS=[
+ ('cms.test_utils.project.sampleapp.menu_extender.get_nodes',
+ 'SampleApp Menu'),
+ ],
+ ROOT_URLCONF='cms.test_utils.project.urls',
+ PASSWORD_HASHERS=(
+ 'django.contrib.auth.hashers.MD5PasswordHasher',
+ ),
+ ALLOWED_HOSTS=['localhost'],
+ TEST_RUNNER='django.test.runner.DiscoverRunner',
+ **dynamic_configs
+ )
diff --git a/test_requirements/django-1.6.txt b/test_requirements/django-1.6.txt
index 5b6d078c247..72fb8d72276 100644
--- a/test_requirements/django-1.6.txt
+++ b/test_requirements/django-1.6.txt
@@ -2,6 +2,6 @@
django>=1.6,<1.7
South==1.0.2
django-reversion<1.8.3
-https://github.com/KristianOellegaard/django-hvad/archive/master.zip#egg=hvad
+https://github.com/KristianOellegaard/django-hvad/archive/ec82b2a8e144ffa6f6349f0dbd0e688c84b77af0.zip#egg=django-hvad
django-classy-tags>=0.5
-django-sekizai>=0.7
\ No newline at end of file
+django-sekizai>=0.7
diff --git a/test_requirements/django-1.7.txt b/test_requirements/django-1.7.txt
index 2e96ca5f8da..30080710b51 100644
--- a/test_requirements/django-1.7.txt
+++ b/test_requirements/django-1.7.txt
@@ -1,6 +1,6 @@
-r requirements_base.txt
django>=1.7,<1.8
django-reversion>=1.8,<1.9
-https://github.com/KristianOellegaard/django-hvad/archive/master.zip
+https://github.com/KristianOellegaard/django-hvad/archive/ec82b2a8e144ffa6f6349f0dbd0e688c84b77af0.zip#egg=django-hvad
django-classy-tags>=0.5
django-sekizai>=0.7
diff --git a/test_requirements/django-1.8.txt b/test_requirements/django-1.8.txt
index 801cb08aeb5..18d810dacb6 100644
--- a/test_requirements/django-1.8.txt
+++ b/test_requirements/django-1.8.txt
@@ -1,6 +1,6 @@
-r requirements_base.txt
-https://github.com/django/django/tarball/stable/1.8.x/django.tar.gz#egg=django
+Django>=1.8,<1.9
django-reversion>=1.8,<1.9
-https://github.com/KristianOellegaard/django-hvad/archive/master.zip
+https://github.com/KristianOellegaard/django-hvad/archive/ec82b2a8e144ffa6f6349f0dbd0e688c84b77af0.zip#egg=django-hvad
https://github.com/yakky/django-sekizai/archive/further_18.zip
https://github.com/vad/django-classy-tags/archive/fix/recursion-in-django18.zip
diff --git a/test_requirements/django-trunk.txt b/test_requirements/django-trunk.txt
index ceae7d2994c..a74fad151ae 100644
--- a/test_requirements/django-trunk.txt
+++ b/test_requirements/django-trunk.txt
@@ -1,4 +1,4 @@
-r requirements_base.txt
https://github.com/django/django/tarball/master/django.tar.gz#egg=django
django-reversion>=1.8
-https://github.com/gabejackson/django-hvad/archive/django_1.7_compat.zip
+https://github.com/gabejackson/django-hvad/archive/django_1.7_compat.zip#egg=django-hvad
diff --git a/test_requirements/requirements_base.txt b/test_requirements/requirements_base.txt
index 7af7a8ee938..95744297546 100644
--- a/test_requirements/requirements_base.txt
+++ b/test_requirements/requirements_base.txt
@@ -22,4 +22,6 @@ django-debug-toolbar
-e git+git://github.com/divio/djangocms-teaser.git#egg=djangocms-teaser
-e git+git://github.com/divio/djangocms-video.git#egg=djangocms-video
-e git+git://github.com/divio/djangocms-link.git#egg=djangocms-link
+https://github.com/ojii/django-better-test/archive/02d4fdc44101e4759d4d1531d7f9178a304cd3d3.zip#egg=django-better-test
+https://github.com/ojii/django-app-manage/archive/3fd3d5f53c27be99002d580e67cee4827107aba7.zip#egg=django-app-manage
pyflakes