Multidb testing for travis #1513

Merged
merged 29 commits into from Dec 20, 2012
Select commit
+686 −679
View
16 .travis.yml
@@ -4,12 +4,22 @@ python:
- "2.6"
- "2.7"
env:
- - DJANGO=test_requirements/django-1.3.txt
- - DJANGO=test_requirements/django-1.4.txt
+ - DJANGO=test_requirements/django-1.3.txt DB='sqlite://localhost/:memory:'
+ - DJANGO=test_requirements/django-1.3.txt DB='mysql://root@127.0.0.1/djangocms_test'
+ - DJANGO=test_requirements/django-1.3.txt DB='postgres://postgres@127.0.0.1/djangocms_test'
+ - DJANGO=test_requirements/django-1.4.txt DB='sqlite://localhost/:memory:'
+ - DJANGO=test_requirements/django-1.4.txt DB='mysql://root@127.0.0.1/djangocms_test'
+ - DJANGO=test_requirements/django-1.4.txt DB='postgres://postgres@127.0.0.1/djangocms_test'
+
+before_script:
+ - sh -c "if [ '$DB' = 'postgres://postgres@127.0.0.1/djangocms_test' ]; then psql -c 'DROP DATABASE IF EXISTS djangocms_test;' -U postgres; fi"
+ - sh -c "if [ '$DB' = 'postgres://postgres@127.0.0.1/djangocms_test' ]; then psql -c 'create database djangocms_test;' -U postgres; fi"
+ - sh -c "if [ '$DB' = 'mysql://root@127.0.0.1/djangocms_test' ]; then mysql -e 'create database IF NOT EXISTS djangocms_test CHARACTER SET utf8 COLLATE utf8_general_ci;'; fi"
+
install:
- pip install -q -r $DJANGO --use-mirrors
script:
- python runtests.py
+ python runtests.py --db $DB
notifications:
email:
recipients:
View
2 cms/models/managers.py
@@ -340,7 +340,7 @@ def for_page(self, page):
"""
# permissions should be managed on the draft page only
page = page.get_draft_object()
- from cms.models import ACCESS_DESCENDANTS, ACCESS_CHILDREN,\
+ from cms.models import ACCESS_DESCENDANTS, ACCESS_CHILDREN, \
ACCESS_PAGE_AND_CHILDREN, ACCESS_PAGE_AND_DESCENDANTS
# code taken from
# https://github.com/divio/django-cms/issues/1113#issuecomment-3376790
View
29 cms/models/pagemodel.py
@@ -20,6 +20,7 @@
from menus.menu_pool import menu_pool
from mptt.models import MPTTModel
from os.path import join
+from datetime import timedelta
import copy
@@ -71,8 +72,8 @@ class Page(MPTTModel):
# Publisher fields
moderator_state = models.SmallIntegerField(_('moderator state'), default=0, blank=True, editable=False)
publisher_is_draft = models.BooleanField(default=1, editable=False, db_index=True)
- #This is misnamed - the one-to-one relation is populated on both ends
- publisher_public = models.OneToOneField('self', related_name='publisher_draft', null=True, editable=False)
+ # This is misnamed - the one-to-one relation is populated on both ends
+ publisher_public = models.OneToOneField('self', related_name='publisher_draft', null=True, editable=False)
publisher_state = models.SmallIntegerField(default=0, editable=False, db_index=True)
# Managers
@@ -134,7 +135,7 @@ def move_page(self, target, position='first-child'):
import cms.signals as cms_signals
cms_signals.page_moved.send(sender=Page, instance=self) # titles get saved before moderation
self.save() # always save the page after move, because of publisher
- moderator.page_changed(self, force_moderation_action = PageModeratorState.ACTION_MOVE)
+ moderator.page_changed(self, force_moderation_action=PageModeratorState.ACTION_MOVE)
# check the slugs
page_utils.check_title_slugs(self)
@@ -302,7 +303,7 @@ def copy_page(self, target, site, position='first-child',
# invalidate the menu for this site
menu_pool.clear(site_id=site.pk)
- return page_copy # return the page_copy or None
+ return page_copy # return the page_copy or None
def save(self, no_signals=False, commit=True, **kwargs):
"""
@@ -318,7 +319,7 @@ def save(self, no_signals=False, commit=True, **kwargs):
# Published pages should always have a publication date
# if the page is published we set the publish date if not set yet.
if self.publication_date is None and self.published:
- self.publication_date = timezone.now()
+ self.publication_date = timezone.now() - timedelta(seconds=5)
if self.reverse_id == "":
self.reverse_id = None
@@ -371,6 +372,8 @@ def publish(self):
if not self.pk:
self.save()
+ if not self.parent_id:
+ self.clear_home_pk_cache()
if self._publisher_can_publish():
if self.publisher_public_id:
# Ensure we have up to date mptt properties
@@ -462,7 +465,7 @@ def unpublish(self):
if not self.publisher_is_draft:
raise PublicIsUnmodifiable('The public instance cannot be unpublished. Use draft.')
- #First, make sure we are in the correct state
+ # First, make sure we are in the correct state
self.published = False
self.save()
public_page = self.get_public_object()
@@ -533,7 +536,7 @@ def delete_with_public(self):
"""
descendants = list(self.get_descendants().order_by('level'))
descendants.reverse()
- #TODO: Use a better exception class - PermissionDenied is not quite right
+ # TODO: Use a better exception class - PermissionDenied is not quite right
for page in descendants:
if not page.delete_requested():
raise PermissionDenied('There are descendant pages not marked for deletion')
@@ -593,7 +596,7 @@ def get_cached_ancestors(self, ascending=True):
self.ancestors_descending = list(self.get_ancestors(ascending))
return self.ancestors_descending
- ### Title object access
+ # ## Title object access
def get_title_obj(self, language=None, fallback=True, version_id=None, force_reload=False):
"""Helper function for accessing wanted / current title.
@@ -776,7 +779,7 @@ def has_view_permission(self, request):
return (user_perm or generic_perm)
else:
- #anonymous user
+ # anonymous user
if is_restricted or not settings.CMS_PUBLIC_FOR == 'all':
# anyonymous user, page has restriction and global access is permitted
return False
@@ -860,15 +863,19 @@ def is_home(self):
def get_home_pk_cache(self):
attr = "%s_home_pk_cache_%s" % (self.publisher_is_draft and "draft" or "public", self.site_id)
- if not hasattr(self, attr):
+ if getattr(self, attr, None) is None:
setattr(self, attr, self.get_object_queryset().get_home(self.site).pk)
return getattr(self, attr)
def set_home_pk_cache(self, value):
+
attr = "%s_home_pk_cache_%s" % (self.publisher_is_draft and "draft" or "public", self.site_id)
setattr(self, attr, value)
home_pk_cache = property(get_home_pk_cache, set_home_pk_cache)
+ def clear_home_pk_cache(self):
+ self.home_pk_cache = None
+
def get_media_path(self, filename):
"""
Returns path (relative to MEDIA_ROOT/MEDIA_URL) to directory for storing page-scope files.
@@ -1022,7 +1029,7 @@ def _publisher_save_public(self, obj):
prev_sibling = self.get_previous_filtered_sibling(**filters)
public_prev_sib = prev_sibling.publisher_public if prev_sibling else None
- if not self.publisher_public_id: # first time published
+ if not self.publisher_public_id: # first time published
# is there anybody on left side?
if public_prev_sib:
obj.insert_at(public_prev_sib, position='right', save=False)
View
15 cms/models/query.py
@@ -68,21 +68,6 @@ def expired(self):
return self.on_site().filter(
publication_end_date__lte=timezone.now())
-# - seems this is not used anymore...
-# def get_pages_with_application(self, path, language):
-# """Returns all pages containing application for current path, or
-# any parrent. Returned list is sorted by path length, longer path first.
-# """
-# paths = levelize_path(path)
-# q = Q()
-# for path in paths:
-# # build q for all the paths
-# q |= Q(title_set__path=path, title_set__language=language)
-# app_pages = self.published().filter(q & Q(title_set__application_urls__gt='')).distinct()
-# # add proper ordering
-# app_pages.query.order_by.extend(('LENGTH(`cms_title`.`path`) DESC',))
-# return app_pages
-
def get_all_pages_with_application(self):
"""Returns all pages containing applications for all sites.
View
7 cms/models/titlemodels.py
@@ -31,12 +31,6 @@ class Meta:
def __unicode__(self):
return u"%s (%s, %s)" % (self.title, self.slug, self.language)
- def save(self, *args, **kwargs):
- # Update the path attribute before saving
- # No longer needed since this is done in signals
- #self.update_path()
- super(Title, self).save(*args, **kwargs)
-
def update_path(self):
# Build path from parent page's path and slug
slug = u'%s' % self.slug
@@ -48,6 +42,7 @@ def update_path(self):
parent_title = Title.objects.get_title(parent_page, language=self.language, language_fallback=True)
if parent_title:
self.path = u'%s/%s' % (parent_title.path, slug)
+
@property
def overwrite_url(self):
View
88 cms/signals.py
@@ -6,10 +6,11 @@
from cms.cache.permissions import (
clear_user_permission_cache, clear_permission_cache)
-from cms.models import (Page, Title, CMSPlugin, PagePermission,
+from cms.models import (Page, Title, CMSPlugin, PagePermission,
GlobalPagePermission, PageUser, PageUserGroup)
from menus.menu_pool import menu_pool
+from cms.models.permissionmodels import PageUserGroup
# fired after page location is changed - is moved from one node to other
page_moved = Signal(providing_args=["instance"])
@@ -20,7 +21,7 @@
# fired after page gets published - copied to public model - there may be more
# than one instances published before this signal gets called
post_publish = Signal(providing_args=["instance"])
-
+
def update_plugin_positions(**kwargs):
plugin = kwargs['instance']
plugins = CMSPlugin.objects.filter(language=plugin.language, placeholder=plugin.placeholder).order_by("position")
@@ -39,13 +40,13 @@ def update_title_paths(instance, **kwargs):
"""
for title in instance.title_set.all():
title.save()
-
+
page_moved.connect(update_title_paths, sender=Page, dispatch_uid="cms.title.update_path")
def update_title(title):
slug = u'%s' % title.slug
-
+
if title.page.is_home():
title.path = ''
elif not title.has_url_overwrite:
@@ -61,52 +62,55 @@ def update_title(title):
def pre_save_title(instance, raw, **kwargs):
"""Save old state to instance and setup path
"""
+
if not instance.page.publisher_is_draft:
+
menu_pool.clear(instance.page.site_id)
-
+
+
if instance.id and not hasattr(instance, "tmp_path"):
instance.tmp_path = None
instance.tmp_application_urls = None
try:
instance.tmp_path, instance.tmp_application_urls = \
Title.objects.filter(pk=instance.id).values_list('path', 'application_urls')[0]
except IndexError:
- pass # no Titles exist for this page yet
-
+ pass # no Titles exist for this page yet
+
# Build path from parent page's path and slug
if instance.has_url_overwrite and instance.path:
instance.path = instance.path.strip(" /")
else:
update_title(instance)
-
+
signals.pre_save.connect(pre_save_title, sender=Title, dispatch_uid="cms.title.presave")
def post_save_title(instance, raw, created, **kwargs):
# Update descendants only if path changed
application_changed = False
prevent_descendants = hasattr(instance, 'tmp_prevent_descendant_update')
- if instance.path != getattr(instance,'tmp_path',None) and not prevent_descendants:
+ if instance.path != getattr(instance, 'tmp_path', None) and not prevent_descendants:
descendant_titles = Title.objects.filter(
- page__lft__gt=instance.page.lft,
- page__rght__lt=instance.page.rght,
+ page__lft__gt=instance.page.lft,
+ page__rght__lt=instance.page.rght,
page__tree_id__exact=instance.page.tree_id,
language=instance.language,
has_url_overwrite=False,
).order_by('page__tree_id', 'page__parent', 'page__lft')
-
+
for descendant_title in descendant_titles:
- descendant_title.path = '' # just reset path
+ descendant_title.path = '' # just reset path
descendant_title.tmp_prevent_descendant_update = True
if descendant_title.application_urls:
application_changed = True
descendant_title.save()
-
+
if not prevent_descendants and \
(instance.application_urls != getattr(instance, 'tmp_application_urls', None) or application_changed):
# fire it if we have some application linked to this page or some descendant
application_post_changed.send(sender=Title, instance=instance)
-
+
# remove temporary attributes
if hasattr(instance, 'tmp_path'):
del instance.tmp_path
@@ -115,7 +119,7 @@ def post_save_title(instance, raw, created, **kwargs):
if prevent_descendants:
del instance.tmp_prevent_descendant_update
-signals.post_save.connect(post_save_title, sender=Title, dispatch_uid="cms.title.postsave")
+signals.post_save.connect(post_save_title, sender=Title, dispatch_uid="cms.title.postsave")
def post_save_user(instance, raw, created, **kwargs):
@@ -131,22 +135,12 @@ def post_save_user(instance, raw, created, **kwargs):
if not creator or not created or not hasattr(creator, 'pk'):
return
from django.db import connection
-
- # i'm not sure if there is a workaround for this, somebody any ideas? What
- # we are doing here is creating PageUser on Top of existing user, i'll do it
- # through plain SQL, its not nice, but...
-
- # TODO: find a better way than an raw sql !!
-
- cursor = connection.cursor()
- query = "INSERT INTO %s (user_ptr_id, created_by_id) VALUES (%d, %d)" % (
- PageUser._meta.db_table,
- instance.pk,
- creator.pk
- )
- cursor.execute(query)
- cursor.close()
-
+
+ page_user = PageUser(user_ptr_id=instance.pk, created_by=creator)
+ page_user.__dict__.update(instance.__dict__)
+ page_user.save()
+
+
def post_save_user_group(instance, raw, created, **kwargs):
"""The same like post_save_user, but for Group, required only when
CMS_PERMISSION.
@@ -160,19 +154,11 @@ def post_save_user_group(instance, raw, created, **kwargs):
creator = get_current_user()
if not creator or not created or creator.is_anonymous():
return
- from django.db import connection
-
- # TODO: same as in post_save_user - raw sql is just not nice - workaround...?
-
- cursor = connection.cursor()
- query = "INSERT INTO %s (group_ptr_id, created_by_id) VALUES (%d, %d)" % (
- PageUserGroup._meta.db_table,
- instance.pk,
- creator.pk
- )
- cursor.execute(query)
- cursor.close()
-
+
+ page_user = PageUserGroup(user_ptr_id=instance.pk, created_by=creator)
+ page_user.__dict__.update(instance.__dict__)
+ page_user.save()
+
if settings.CMS_PERMISSION:
# only if permissions are in use
from django.contrib.auth.models import User, Group
@@ -191,7 +177,7 @@ def pre_save_page(instance, raw, **kwargs):
pass
-def post_save_page_moderator(instance, raw, created, **kwargs):
+def post_save_page_moderator(instance, raw, created, **kwargs):
"""Helper post save signal.
"""
old_page = instance.old_page
@@ -200,7 +186,7 @@ def post_save_page_moderator(instance, raw, created, **kwargs):
from cms.utils.moderator import page_changed
if not old_page:
page_changed(instance, old_page)
-
+
def post_save_page(instance, **kwargs):
if instance.old_page is None or instance.old_page.parent_id != instance.parent_id:
for page in instance.get_descendants():
@@ -263,18 +249,18 @@ def pre_save_delete_page(instance, **kwargs):
signals.pre_save.connect(pre_save_user, sender=PageUser)
signals.pre_delete.connect(pre_delete_user, sender=PageUser)
-
+
signals.pre_save.connect(pre_save_group, sender=Group)
signals.pre_delete.connect(pre_delete_group, sender=Group)
signals.pre_save.connect(pre_save_group, sender=PageUserGroup)
signals.pre_delete.connect(pre_delete_group, sender=PageUserGroup)
-
+
signals.pre_save.connect(pre_save_pagepermission, sender=PagePermission)
signals.pre_delete.connect(pre_delete_pagepermission, sender=PagePermission)
-
+
signals.pre_save.connect(pre_save_globalpagepermission, sender=GlobalPagePermission)
signals.pre_delete.connect(pre_delete_globalpagepermission, sender=GlobalPagePermission)
-
+
signals.pre_save.connect(pre_save_delete_page, sender=Page)
signals.pre_delete.connect(pre_save_delete_page, sender=Page)
View
27 cms/test_utils/cli.py
@@ -2,25 +2,27 @@
from distutils.version import LooseVersion
import django
import os
+import dj_database_url
gettext = lambda s: s
urlpatterns = []
DJANGO_1_3 = LooseVersion(django.get_version()) < LooseVersion('1.4')
-def configure(**extra):
+def configure(db_url, **extra):
from django.conf import settings
os.environ['DJANGO_SETTINGS_MODULE'] = 'cms.test_utils.cli'
+ if not 'DATABASES' in extra:
+ DB = dj_database_url.parse(db_url)
+ else:
+ DB = {}
defaults = dict(
CACHE_BACKEND='locmem:///',
DEBUG=True,
TEMPLATE_DEBUG=True,
DATABASE_SUPPORTS_TRANSACTIONS=True,
DATABASES={
- 'default': {
- 'ENGINE': 'django.db.backends.sqlite3',
- 'NAME': ':memory:',
- }
+ 'default': DB
},
SITE_ID=1,
USE_I18N=True,
@@ -55,12 +57,14 @@ def configure(**extra):
],
MIDDLEWARE_CLASSES=[
'django.contrib.sessions.middleware.SessionMiddleware',
- 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.doc.XViewMiddleware',
'django.middleware.common.CommonMiddleware',
+ 'django.middleware.transaction.TransactionMiddleware',
+ 'django.middleware.cache.FetchFromCacheMiddleware',
'cms.middleware.user.CurrentUserMiddleware',
'cms.middleware.page.CurrentPageMiddleware',
'cms.middleware.toolbar.ToolbarMiddleware',
@@ -191,10 +195,10 @@ def configure(**extra):
"name": "extra context"
},
},
- CMS_SOFTROOT = True,
- CMS_PERMISSION = True,
- CMS_PUBLIC_FOR = 'all',
- CMS_CACHE_DURATIONS = {
+ CMS_SOFTROOT=True,
+ CMS_PERMISSION=True,
+ CMS_PUBLIC_FOR='all',
+ CMS_CACHE_DURATIONS={
'menus': 0,
'content': 0,
'permissions': 0,
@@ -229,13 +233,10 @@ def configure(**extra):
from django.utils.functional import empty
settings._wrapped = empty
defaults.update(extra)
-
settings.configure(**defaults)
from cms.conf import patch_settings
patch_settings()
from south.management.commands import patch_for_test_db_setup
patch_for_test_db_setup()
from django.contrib import admin
-
-
admin.autodiscover()
View
7 cms/test_utils/testcases.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
from cms.models import Page
-from cms.test_utils.util.context_managers import (UserLoginContext,
+from cms.test_utils.util.context_managers import (UserLoginContext,
SettingsOverride)
from django.conf import settings
from django.contrib.auth.models import User, AnonymousUser
@@ -15,6 +15,7 @@
import sys
import urllib
import warnings
+from cms.utils.permissions import set_current_user
URL_CMS_PAGE = "/en/admin/cms/page/"
@@ -78,13 +79,15 @@ def _fixture_setup(self):
self.create_fixtures()
activate("en")
+
def create_fixtures(self):
pass
def _post_teardown(self):
# Needed to clean the menu keys cache, see menu.menu_pool.clear()
menu_pool.clear()
super(CMSTestCase, self)._post_teardown()
+ set_current_user(None)
def login_user_context(self, user):
return UserLoginContext(self, user)
@@ -173,7 +176,7 @@ def copy_page(self, page, target_page):
self.assertEquals(response.status_code, 200)
# Altered to reflect the new django-js jsonified response messages
self.assertEquals(response.content, '{"status": 200, "content": "ok"}')
-
+
title = page.title_set.all()[0]
copied_slug = get_available_slug(title)
View
203 cms/tests/admin.py
@@ -13,7 +13,7 @@
from cms.models.titlemodels import Title
from cms.plugins.text.models import Text
from cms.test_utils import testcases as base
-from cms.test_utils.testcases import (CMSTestCase, URL_CMS_PAGE_DELETE,
+from cms.test_utils.testcases import (CMSTestCase, URL_CMS_PAGE_DELETE,
URL_CMS_PAGE, URL_CMS_TRANSLATION_DELETE)
from cms.test_utils.util.context_managers import SettingsOverride
from cms.test_utils.util.mock import AttributeObject
@@ -23,7 +23,7 @@
from django.contrib.auth.models import User, Permission, AnonymousUser
from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse
-from django.http import (Http404, HttpResponseBadRequest, HttpResponseForbidden,
+from django.http import (Http404, HttpResponseBadRequest, HttpResponseForbidden,
HttpResponse)
from django.utils.encoding import smart_str
from menus.menu_pool import menu_pool
@@ -35,7 +35,7 @@ class AdminTestsBase(CMSTestCase):
@property
def admin_class(self):
return site._registry[Page]
-
+
def _get_guys(self, admin_only=False):
admin = self.get_superuser()
if admin_only:
@@ -60,9 +60,9 @@ def _get_guys(self, admin_only=False):
)
gpp.sites = Site.objects.all()
return admin, normal_guy
-
+
class AdminTestCase(AdminTestsBase):
-
+
def test_edit_does_not_reset_page_adv_fields(self):
"""
Makes sure that if a non-superuser with no rights to edit advanced page
@@ -72,11 +72,11 @@ def test_edit_does_not_reset_page_adv_fields(self):
NEW_PAGE_NAME = 'Test page 2'
REVERSE_ID = 'Test'
OVERRIDE_URL = 'my/override/url'
-
+
admin, normal_guy = self._get_guys()
-
+
site = Site.objects.get(pk=1)
-
+
# The admin creates the page
page = create_page(OLD_PAGE_NAME, "nav_playground.html", "en",
site=site, created_by=admin)
@@ -86,17 +86,17 @@ def test_edit_does_not_reset_page_adv_fields(self):
title.has_url_overwrite = True
title.path = OVERRIDE_URL
title.save()
-
+
self.assertEqual(page.get_title(), OLD_PAGE_NAME)
self.assertEqual(page.reverse_id, REVERSE_ID)
self.assertEqual(title.overwrite_url, OVERRIDE_URL)
-
+
# The user edits the page (change the page name for ex.)
page_data = {
- 'title': NEW_PAGE_NAME,
- 'slug': page.get_slug(),
+ 'title': NEW_PAGE_NAME,
+ 'slug': page.get_slug(),
'language': title.language,
- 'site': page.site.pk,
+ 'site': page.site.pk,
'template': page.template,
}
# required only if user haves can_change_permission
@@ -106,25 +106,25 @@ def test_edit_does_not_reset_page_adv_fields(self):
page_data['pagepermission_set-2-TOTAL_FORMS'] = 0
page_data['pagepermission_set-2-INITIAL_FORMS'] = 0
page_data['pagepermission_set-2-MAX_NUM_FORMS'] = 0
-
+
with self.login_user_context(normal_guy):
- resp = self.client.post(base.URL_CMS_PAGE_CHANGE % page.pk, page_data,
+ resp = self.client.post(base.URL_CMS_PAGE_CHANGE % page.pk, page_data,
follow=True)
self.assertEqual(resp.status_code, 200)
self.assertTemplateNotUsed(resp, 'admin/login.html')
page = Page.objects.get(pk=page.pk)
-
+
self.assertEqual(page.get_title(), NEW_PAGE_NAME)
self.assertEqual(page.reverse_id, REVERSE_ID)
title = page.get_title_obj()
self.assertEqual(title.overwrite_url, OVERRIDE_URL)
-
+
# The admin edits the page (change the page name for ex.)
page_data = {
- 'title': OLD_PAGE_NAME,
- 'slug': page.get_slug(),
+ 'title': OLD_PAGE_NAME,
+ 'slug': page.get_slug(),
'language': title.language,
- 'site': page.site.pk,
+ 'site': page.site.pk,
'template': page.template,
'reverse_id': page.reverse_id,
}
@@ -135,19 +135,19 @@ def test_edit_does_not_reset_page_adv_fields(self):
page_data['pagepermission_set-2-TOTAL_FORMS'] = 0
page_data['pagepermission_set-2-INITIAL_FORMS'] = 0
page_data['pagepermission_set-2-MAX_NUM_FORMS'] = 0
-
+
with self.login_user_context(admin):
- resp = self.client.post(base.URL_CMS_PAGE_CHANGE % page.pk, page_data,
+ resp = self.client.post(base.URL_CMS_PAGE_CHANGE % page.pk, page_data,
follow=True)
self.assertEqual(resp.status_code, 200)
self.assertTemplateNotUsed(resp, 'admin/login.html')
page = Page.objects.get(pk=page.pk)
-
+
self.assertEqual(page.get_title(), OLD_PAGE_NAME)
self.assertEqual(page.reverse_id, REVERSE_ID)
title = page.get_title_obj()
self.assertEqual(title.overwrite_url, None)
-
+
def test_edit_does_not_reset_apphook(self):
"""
Makes sure that if a non-superuser with no rights to edit advanced page
@@ -157,11 +157,11 @@ def test_edit_does_not_reset_apphook(self):
NEW_PAGE_NAME = 'Test page 2'
REVERSE_ID = 'Test'
APPLICATION_URLS = 'project.sampleapp.urls'
-
+
admin, normal_guy = self._get_guys()
-
+
site = Site.objects.get(pk=1)
-
+
# The admin creates the page
page = create_page(OLD_PAGE_NAME, "nav_playground.html", "en",
site=site, created_by=admin)
@@ -171,17 +171,17 @@ def test_edit_does_not_reset_apphook(self):
title.has_url_overwrite = True
title.application_urls = APPLICATION_URLS
title.save()
-
+
self.assertEqual(page.get_title(), OLD_PAGE_NAME)
self.assertEqual(page.reverse_id, REVERSE_ID)
self.assertEqual(title.application_urls, APPLICATION_URLS)
-
+
# The user edits the page (change the page name for ex.)
page_data = {
- 'title': NEW_PAGE_NAME,
- 'slug': page.get_slug(),
+ 'title': NEW_PAGE_NAME,
+ 'slug': page.get_slug(),
'language': title.language,
- 'site': page.site.pk,
+ 'site': page.site.pk,
'template': page.template,
}
# required only if user haves can_change_permission
@@ -191,25 +191,25 @@ def test_edit_does_not_reset_apphook(self):
page_data['pagepermission_set-2-TOTAL_FORMS'] = 0
page_data['pagepermission_set-2-INITIAL_FORMS'] = 0
page_data['pagepermission_set-2-MAX_NUM_FORMS'] = 0
-
+
with self.login_user_context(normal_guy):
- resp = self.client.post(base.URL_CMS_PAGE_CHANGE % page.pk, page_data,
+ resp = self.client.post(base.URL_CMS_PAGE_CHANGE % page.pk, page_data,
follow=True)
self.assertEqual(resp.status_code, 200)
self.assertTemplateNotUsed(resp, 'admin/login.html')
page = Page.objects.get(pk=page.pk)
-
+
self.assertEqual(page.get_title(), NEW_PAGE_NAME)
self.assertEqual(page.reverse_id, REVERSE_ID)
title = page.get_title_obj()
self.assertEqual(title.application_urls, APPLICATION_URLS)
-
+
# The admin edits the page (change the page name for ex.)
page_data = {
- 'title': OLD_PAGE_NAME,
- 'slug': page.get_slug(),
+ 'title': OLD_PAGE_NAME,
+ 'slug': page.get_slug(),
'language': title.language,
- 'site': page.site.pk,
+ 'site': page.site.pk,
'template': page.template,
'reverse_id': page.reverse_id,
}
@@ -220,14 +220,14 @@ def test_edit_does_not_reset_apphook(self):
page_data['pagepermission_set-2-TOTAL_FORMS'] = 0
page_data['pagepermission_set-2-INITIAL_FORMS'] = 0
page_data['pagepermission_set-2-MAX_NUM_FORMS'] = 0
-
+
with self.login_user_context(admin):
- resp = self.client.post(base.URL_CMS_PAGE_CHANGE % page.pk, page_data,
+ resp = self.client.post(base.URL_CMS_PAGE_CHANGE % page.pk, page_data,
follow=True)
self.assertEqual(resp.status_code, 200)
self.assertTemplateNotUsed(resp, 'admin/login.html')
page = Page.objects.get(pk=page.pk)
-
+
self.assertEqual(page.get_title(), OLD_PAGE_NAME)
self.assertEqual(page.reverse_id, REVERSE_ID)
title = page.get_title_obj()
@@ -272,7 +272,7 @@ def test_delete_translation(self):
self.assertEqual(response.status_code, 200)
response = self.client.post(URL_CMS_TRANSLATION_DELETE % page.pk, {'language': 'de'})
self.assertRedirects(response, URL_CMS_PAGE)
-
+
def test_change_template(self):
admin, staff = self._get_guys()
request = self.get_request('/admin/cms/page/1/', 'en')
@@ -301,38 +301,38 @@ def test_get_permissions(self):
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertTemplateNotUsed(response, 'admin/login.html')
-
+
def test_changelist_items(self):
admin = self.get_superuser()
- first_level_page = create_page('level1', 'nav_playground.html', 'en')
+ first_level_page = create_page('level1', 'nav_playground.html', 'en')
second_level_page_top = create_page('level21', "nav_playground.html", "en",
- created_by=admin, published=True, parent= first_level_page)
+ created_by=admin, published=True, parent=first_level_page)
second_level_page_bottom = create_page('level22', "nav_playground.html", "en",
- created_by=admin, published=True, parent= self.reload(first_level_page))
+ created_by=admin, published=True, parent=self.reload(first_level_page))
third_level_page = create_page('level3', "nav_playground.html", "en",
- created_by=admin, published=True, parent= second_level_page_top)
+ created_by=admin, published=True, parent=second_level_page_top)
self.assertEquals(Page.objects.all().count(), 4)
-
+
url = reverse('admin:cms_%s_changelist' % Page._meta.module_name)
request = self.get_request(url)
request.session = {}
request.user = admin
-
+
page_admin = site._registry[Page]
cl_params = [request, page_admin.model, page_admin.list_display,
page_admin.list_display_links, page_admin.list_filter,
- page_admin.date_hierarchy, page_admin.search_fields,
+ page_admin.date_hierarchy, page_admin.search_fields,
page_admin.list_select_related, page_admin.list_per_page]
if hasattr(page_admin, 'list_max_show_all'): # django 1.4
cl_params.append(page_admin.list_max_show_all)
cl_params.extend([page_admin.list_editable, page_admin])
cl = CMSChangeList(*tuple(cl_params))
-
+
cl.set_items(request)
-
-
+
+
root_page = cl.get_items()[0]
self.assertEqual(root_page, first_level_page)
@@ -347,29 +347,29 @@ def test_changelist_tree(self):
Cookie set below is just a forged example (from live session)
"""
admin = self.get_superuser()
- first_level_page = create_page('level1', 'nav_playground.html', 'en')
+ first_level_page = create_page('level1', 'nav_playground.html', 'en')
second_level_page_top = create_page('level21', "nav_playground.html", "en",
- created_by=admin, published=True, parent= first_level_page)
+ created_by=admin, published=True, parent=first_level_page)
second_level_page_bottom = create_page('level22', "nav_playground.html", "en",
- created_by=admin, published=True, parent= self.reload(first_level_page))
+ created_by=admin, published=True, parent=self.reload(first_level_page))
third_level_page = create_page('level3', "nav_playground.html", "en",
- created_by=admin, published=True, parent= second_level_page_top)
+ created_by=admin, published=True, parent=second_level_page_top)
url = reverse('admin:cms_%s_changelist' % Page._meta.module_name)
self.client.login(username='admin', password='admin')
self.client.cookies['djangocms_nodes_open'] = 'page_1%2Cpage_2'
response = self.client.get(url)
self.assertEquals(response.status_code, 200)
- self.assertEquals(response.context["open_menu_trees"], [1,2])
+ self.assertEquals(response.context["open_menu_trees"], [1, 2])
# tests descendants method for the lazy load ajax call
url = "%s%d/descendants/" % (url, first_level_page.pk)
response = self.client.get(url)
self.assertEquals(response.status_code, 200)
# should include both direct descendant pages
- self.assertTrue('id="page_2"' in response.content)
- self.assertTrue('id="page_3"' in response.content)
+ self.assertTrue('id="page_%s"' % second_level_page_top.pk in response.content)
+ self.assertTrue('id="page_%s"' % second_level_page_bottom.pk in response.content)
# but not any further down the tree
- self.assertFalse('id="page_4"' in response.content)
+ self.assertFalse('id="page_%s"' % third_level_page.pk in response.content)
class AdminFieldsetTests(CMSTestCase):
@@ -384,7 +384,7 @@ def validate_attributes(self, a, b, ignore=None):
a_attr = getattr(a, attr)
b_attr = getattr(b, attr)
self.assertEqual(a_attr, b_attr)
-
+
def test_no_moderator(self):
control = AttributeObject()
contribute_fieldsets(control)
@@ -400,7 +400,7 @@ def test_no_menu_title_overwrite(self):
self.validate_attributes(control, experiment, ['fieldsets', 'general_fields'])
self.assertEqual(control.general_fields[0], ('title', 'menu_title'))
self.assertEqual(experiment.general_fields[0], 'title')
-
+
def test_no_softroot(self):
with SettingsOverride(CMS_SOFTROOT=True):
control = AttributeObject()
@@ -411,7 +411,7 @@ def test_no_softroot(self):
self.validate_attributes(control, experiment, ['fieldsets', 'advanced_fields'])
self.assertTrue('soft_root' in control.advanced_fields)
self.assertFalse('soft_root' in experiment.advanced_fields)
-
+
def test_dates(self):
with SettingsOverride(CMS_SHOW_START_DATE=False, CMS_SHOW_END_DATE=False):
control = AttributeObject()
@@ -438,7 +438,7 @@ def test_dates(self):
self.assertFalse('publication_date' in experiment1.general_fields, experiment1.general_fields)
self.assertTrue('publication_date' in experiment2.general_fields, experiment2.general_fields)
self.assertFalse('publication_date' in experiment3.general_fields, experiment3.general_fields)
-
+
def test_no_seo(self):
with SettingsOverride(CMS_SEO_FIELDS=True):
control = AttributeObject()
@@ -449,7 +449,7 @@ def test_no_seo(self):
self.validate_attributes(control, experiment, ['fieldsets', 'seo_fields'])
self.assertEqual(control.seo_fields, ['page_title', 'meta_description', 'meta_keywords'])
self.assertFalse(experiment.seo_fields, [])
-
+
def test_url_overwrite(self):
with SettingsOverride(CMS_URL_OVERWRITE=False):
control = AttributeObject()
@@ -460,7 +460,7 @@ def test_url_overwrite(self):
self.validate_attributes(control, experiment, ['fieldsets', 'advanced_fields'])
self.assertFalse('overwrite_url' in control.advanced_fields, control.advanced_fields)
self.assertTrue('overwrite_url' in experiment.advanced_fields, experiment.advanced_fields)
-
+
def test_no_cms_enabled_menus(self):
control = AttributeObject()
contribute_fieldsets(control)
@@ -472,7 +472,7 @@ def test_no_cms_enabled_menus(self):
self.validate_attributes(control, experiment, ['fieldsets', 'advanced_fields'])
self.assertTrue('navigation_extenders' in control.advanced_fields, control.advanced_fields)
self.assertFalse('navigation_extenders' in experiment.advanced_fields, experiment.advanced_fields)
-
+
def test_redirects(self):
with SettingsOverride(CMS_REDIRECTS=False):
control = AttributeObject()
@@ -483,8 +483,8 @@ def test_redirects(self):
self.validate_attributes(control, experiment, ['fieldsets', 'advanced_fields'])
self.assertFalse('redirect' in control.advanced_fields, control.advanced_fields)
self.assertTrue('redirect' in experiment.advanced_fields, experiment.advanced_fields)
-
-
+
+
def test_no_apphooks(self):
def func_true(self):
return True
@@ -501,7 +501,7 @@ def func_false(self):
self.assertTrue('application_urls' in control.advanced_fields, control.advanced_fields)
self.assertFalse('application_urls' in experiment.advanced_fields, control.advanced_fields)
apphook_pool.get_apphooks = old_get_apphooks
-
+
class AdminListFilterTests(CMSTestCase):
def test_no_moderator(self):
@@ -521,25 +521,25 @@ def test_no_softroot(self):
class AdminTests(AdminTestsBase):
# TODO: needs tests for actual permissions, not only superuser/normaluser
-
+
def setUp(self):
self.page = create_page("testpage", "nav_playground.html", "en")
-
+
def get_admin(self):
usr = User(username="admin", email="admin@django-cms.org", is_staff=True, is_superuser=True)
usr.set_password("admin")
usr.save()
return usr
-
+
def get_permless(self):
usr = User(username="permless", email="permless@django-cms.org", is_staff=True)
usr.set_password("permless")
usr.save()
return usr
-
+
def get_page(self):
return self.page
-
+
def test_get_moderation_state(self):
page = self.get_page()
permless = self.get_permless()
@@ -552,7 +552,7 @@ def test_get_moderation_state(self):
request = self.get_request()
response = self.admin_class.get_moderation_states(request, page.pk)
self.assertEqual(response.status_code, 200)
-
+
def test_remove_delete(self):
page = self.get_page()
permless = self.get_permless()
@@ -570,7 +570,7 @@ def test_remove_delete(self):
self.assertEqual(response.status_code, 302)
page = self.reload(page)
self.assertEqual(page.pagemoderatorstate_set.get_delete_actions().count(), 0)
-
+
def test_change_status(self):
page = self.get_page()
permless = self.get_permless()
@@ -631,15 +631,15 @@ def test_publish_page_requires_perms(self):
with self.login_user_context(permless):
request = self.get_request()
request.method = "POST"
- response = self.admin_class.publish_page(request, 1)
+ response = self.admin_class.publish_page(request, Page.objects.all()[0].pk)
self.assertEqual(response.status_code, 403)
def test_revert_page_requires_perms(self):
permless = self.get_permless()
with self.login_user_context(permless):
request = self.get_request()
request.method = "POST"
- response = self.admin_class.revert_page(request, 1)
+ response = self.admin_class.revert_page(request, Page.objects.all()[0].pk)
self.assertEqual(response.status_code, 403)
def test_revert_page_redirects(self):
@@ -706,7 +706,7 @@ def test_move_plugin(self):
response = self.admin_class.move_plugin(request)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.content, "ok")
-
+
def test_preview_page(self):
permless = self.get_permless()
with self.login_user_context(permless):
@@ -733,11 +733,13 @@ def test_preview_page(self):
site = Site.objects.create(domain='django-cms.org', name='django-cms')
page.site = site
page.save()
+ page.publish()
+ self.assertTrue(page.is_home())
response = self.admin_class.preview_page(request, page.pk)
self.assertEqual(response.status_code, 302)
self.assertEqual(response['Location'],
'http://django-cms.org%s?preview=1&draft=1' % base_url)
-
+
def test_too_many_plugins_global(self):
conf = {
'body': {
@@ -761,7 +763,7 @@ def test_too_many_plugins_global(self):
}
response = self.client.post(url, data)
self.assertEqual(response.status_code, HttpResponseBadRequest.status_code)
-
+
def test_too_many_plugins_type(self):
conf = {
'body': {
@@ -788,24 +790,24 @@ def test_too_many_plugins_type(self):
class NoDBAdminTests(CMSTestCase):
-
+
@property
def admin_class(self):
return site._registry[Page]
-
+
def test_lookup_allowed_site__exact(self):
self.assertTrue(self.admin_class.lookup_allowed('site__exact', '1'))
-
+
def test_lookup_allowed_published(self):
self.assertTrue(self.admin_class.lookup_allowed('published', value='1'))
class PluginPermissionTests(AdminTestsBase):
-
+
def setUp(self):
self._page = create_page('test page', 'nav_playground.html', 'en')
self._placeholder = self._page.placeholders.all()[0]
-
+
def _get_admin(self):
admin = User(
username='admin',
@@ -816,10 +818,10 @@ def _get_admin(self):
admin.set_password('admin')
admin.save()
return admin
-
+
def _get_page_admin(self):
return admin.site._registry[Page]
-
+
def _give_permission(self, user, model, permission_type, save=True):
codename = '%s_%s' % (permission_type, model._meta.object_name.lower())
user.user_permissions.add(Permission.objects.get(codename=codename))
@@ -855,7 +857,7 @@ def _give_cms_permissions(self, user, save=True):
def _create_plugin(self):
plugin = add_plugin(self._placeholder, 'TextPlugin', 'en')
return plugin
-
+
def test_plugin_add_requires_permissions(self):
"""User tries to add a plugin but has no permissions. He can add the plugin after he got the permissions"""
admin = self._get_admin()
@@ -974,11 +976,11 @@ def test_clean_overwrite_url(self):
'slug': 'test-page',
'language': 'en',
'overwrite_url': '/overwrite/url/',
- 'site': Site.objects.get_current().pk,
+ 'site': Site.objects.get_current().pk,
'template': settings.CMS_TEMPLATES[0][0],
'published': True
}
-
+
form = PageForm(data)
self.assertTrue(form.is_valid(), form.errors.as_text())
# WTF? WHY DOES form.save() not handle this stuff???
@@ -1049,7 +1051,7 @@ class AdminPageEditContentSizeTests(AdminTestsBase):
The test relates to extra=0
at PagePermissionInlineAdminForm and ViewRestrictionInlineAdmin
"""
-
+
def test_editpage_contentsize(self):
"""
Expected a username only 2 times in the content, but a relationship
@@ -1059,7 +1061,7 @@ def test_editpage_contentsize(self):
admin = self.get_superuser()
PAGE_NAME = 'TestPage'
USER_NAME = 'test_size_user_0'
- site = Site.objects.get(pk = 1)
+ site = Site.objects.get(pk=1)
page = create_page(PAGE_NAME, "nav_playground.html", "en", site=site, created_by=admin)
page.save()
self._page = page
@@ -1072,17 +1074,18 @@ def test_editpage_contentsize(self):
# create additionals user and reload the page
User.objects.create(username=USER_NAME, is_active=True)
user_count = User.objects.count()
- more_users_in_db = old_user_count < user_count
+ more_users_in_db = old_user_count < user_count
# we have more users
- self.assertTrue(more_users_in_db,"New users got NOT created")
+ self.assertTrue(more_users_in_db, "New users got NOT created")
response = self.client.get(url)
new_response_size = len(response.content)
page_size_grown = old_response_size < new_response_size
# expect that the pagesize gets influenced by the useramount of the system
- self.assertTrue(page_size_grown,"Page size has not grown after user creation")
+ self.assertTrue(page_size_grown, "Page size has not grown after user creation")
# usernames are only 2 times in content
text = smart_str(response.content, response._charset)
+
foundcount = text.count(USER_NAME)
# 2 forms contain usernames as options
self.assertEqual(foundcount, 2, "Username %s appeared %s times in response.content, expected 2 times" % (USER_NAME, foundcount))
-
+
View
2 cms/tests/apphooks.py
@@ -11,6 +11,7 @@
from django.contrib.auth.models import User
from django.core.urlresolvers import clear_url_caches, reverse
import sys
+from cms.models.pagemodel import Page
@@ -394,6 +395,7 @@ def test_page_language_url_for_apphook(self):
output = tag.get_context(fake_context, 'en')
url = output['content']
+
self.assertEqual(url, '/en/child_page/child_child_page/extra_1/')
output = tag.get_context(fake_context, 'de')
View
38 cms/tests/forms.py
@@ -4,15 +4,15 @@
from cms.admin.forms import PageUserForm
from cms.api import create_page, create_page_user
from cms.forms.fields import PageSelectFormField, SuperLazyIterator
-from cms.forms.utils import (get_site_choices, get_page_choices,
+from cms.forms.utils import (get_site_choices, get_page_choices,
update_site_and_page_choices)
from cms.test_utils.testcases import CMSTestCase
from cms.test_utils.util.context_managers import SettingsOverride
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
from django.core.cache import cache
-class Mock_PageSelectFormField(PageSelectFormField):
+class Mock_PageSelectFormField(PageSelectFormField):
def __init__(self, required=False):
# That's to have a proper mock object, without having to resort
# to dirtier tricks. We want to test *just* compress here.
@@ -23,19 +23,19 @@ def __init__(self, required=False):
class FormsTestCase(CMSTestCase):
def setUp(self):
cache.clear()
-
+
def test_get_site_choices(self):
result = get_site_choices()
self.assertEquals(result, [])
-
+
def test_get_page_choices(self):
result = get_page_choices()
self.assertEquals(result, [('', '----')])
-
+
def test_get_site_choices_without_moderator(self):
result = get_site_choices()
self.assertEquals(result, [])
-
+
def test_get_site_choices_without_moderator_with_superuser(self):
# boilerplate (creating a page)
user_super = User(username="super", is_staff=True, is_active=True,
@@ -46,8 +46,8 @@ def test_get_site_choices_without_moderator_with_superuser(self):
create_page("home", "nav_playground.html", "en", created_by=user_super)
# The proper test
result = get_site_choices()
- self.assertEquals(result, [(1,'example.com')])
-
+ self.assertEquals(result, [(1, 'example.com')])
+
def test_compress_function_raises_when_page_is_none(self):
raised = False
try:
@@ -58,22 +58,22 @@ def test_compress_function_raises_when_page_is_none(self):
except forms.ValidationError:
raised = True
self.assertTrue(raised)
-
+
def test_compress_function_returns_none_when_not_required(self):
fake_field = Mock_PageSelectFormField(required=False)
data_list = (0, None) #(site_id, page_id) dsite-id is not used
result = fake_field.compress(data_list)
self.assertEquals(result, None)
-
+
def test_compress_function_returns_none_when_no_data_list(self):
fake_field = Mock_PageSelectFormField(required=False)
data_list = None
result = fake_field.compress(data_list)
self.assertEquals(result, None)
-
+
def test_compress_function_gets_a_page_when_one_exists(self):
# boilerplate (creating a page)
- user_super = User(username="super", is_staff=True, is_active=True,
+ user_super = User(username="super", is_staff=True, is_active=True,
is_superuser=True)
user_super.set_password("super")
user_super.save()
@@ -83,11 +83,11 @@ def test_compress_function_gets_a_page_when_one_exists(self):
fake_field = Mock_PageSelectFormField()
data_list = (0, home_page.pk) #(site_id, page_id) dsite-id is not used
result = fake_field.compress(data_list)
- self.assertEquals(home_page,result)
-
+ self.assertEquals(home_page, result)
+
def test_update_site_and_page_choices(self):
Site.objects.all().delete()
- site = Site.objects.create(domain='http://www.django-cms.org', name='Django CMS')
+ site = Site.objects.create(domain='http://www.django-cms.org', name='Django CMS', pk=1)
page1 = create_page('Page 1', 'nav_playground.html', 'en', site=site)
page2 = create_page('Page 2', 'nav_playground.html', 'de', site=site)
page3 = create_page('Page 3', 'nav_playground.html', 'en',
@@ -104,17 +104,17 @@ def test_update_site_and_page_choices(self):
])
self.assertEqual(site_choices, [(site.pk, site.name)])
-
+
def test_superlazy_iterator_behaves_properly_for_sites(self):
normal_result = get_site_choices()
lazy_result = SuperLazyIterator(get_site_choices)
-
+
self.assertEquals(normal_result, list(lazy_result))
-
+
def test_superlazy_iterator_behaves_properly_for_pages(self):
normal_result = get_page_choices()
lazy_result = SuperLazyIterator(get_page_choices)
-
+
self.assertEquals(normal_result, list(lazy_result))
def test_page_user_form_initial(self):
View
20 cms/tests/management.py
@@ -21,12 +21,12 @@ def test_list_apphooks(self):
apps = ["cms", "menus", "sekizai", "cms.test_utils.project.sampleapp"]
with SettingsOverride(INSTALLED_APPS=apps):
create_page('Hello Title', "nav_playground.html", "en", apphook=APPHOOK)
- self.assertEqual(Title.objects.filter(application_urls=APPHOOK).count(), 1)
+ self.assertEqual(Title.objects.filter(application_urls=APPHOOK).count(), 1)
command = cms.Command()
command.stdout = out
command.handle("list", "apphooks", interactive=False)
self.assertEqual(out.getvalue(), "SampleApp\n")
-
+
def test_uninstall_apphooks_without_apphook(self):
out = StringIO()
command = cms.Command()
@@ -56,17 +56,13 @@ def test_list_plugins(self):
add_plugin(placeholder, "LinkPlugin", "en",
name="A Link", url="https://www.django-cms.org")
self.assertEqual(
- CMSPlugin.objects.filter(plugin_type=PLUGIN).count(),
- 2)
+ CMSPlugin.objects.filter(plugin_type=PLUGIN).count(),
+ 2)
self.assertEqual(
- CMSPlugin.objects.filter(plugin_type="LinkPlugin").count(),
- 1)
- for plugin in plugin_report():
- print plugin
- # command.stdout = out
- # command.handle("list", "plugins", interactive=False)
- # self.assertEqual(out.getvalue(), "LinkPlugin\nTextPlugin\n")
-
+ CMSPlugin.objects.filter(plugin_type="LinkPlugin").count(),
+ 1)
+
+
def test_uninstall_plugins_without_plugin(self):
out = StringIO()
command = cms.Command()
View
240 cms/tests/menu.py
@@ -5,10 +5,10 @@
from cms.menu import CMSMenu, get_visible_pages
from cms.models import Page
from cms.models.permissionmodels import GlobalPagePermission, PagePermission
-from cms.test_utils.fixtures.menus import (MenusFixture, SubMenusFixture,
+from cms.test_utils.fixtures.menus import (MenusFixture, SubMenusFixture,
SoftrootFixture)
from cms.test_utils.testcases import SettingsOverrideTestCase
-from cms.test_utils.util.context_managers import (SettingsOverride,
+from cms.test_utils.util.context_managers import (SettingsOverride,
LanguageOverride)
from cms.test_utils.util.mock import AttributeObject
from cms.utils.i18n import force_language
@@ -21,6 +21,7 @@
from menus.menu_pool import menu_pool, _build_nodes_inner_for_one_menu
from menus.models import CacheKey
from menus.utils import mark_descendants, find_selected, cut_levels
+from django.utils.unittest.case import skipUnless
@@ -46,7 +47,7 @@ def setUp(self):
menu_pool.menus = {'CMSMenu': self.old_menu['CMSMenu']}
menu_pool.clear(settings.SITE_ID)
activate("en")
-
+
def tearDown(self):
menu_pool.menus = self.old_menu
super(BaseMenuTest, self).tearDown()
@@ -81,22 +82,22 @@ def test_menu_failfast_on_invalid_usage(self):
with SettingsOverride(DEBUG=True, TEMPLATE_DEBUG=True):
tpl = Template("{% load menu_tags %}{% show_menu 0 0 0 0 'menu/menu.html' child %}")
self.assertRaises(TemplateSyntaxError, tpl.render, context)
-
+
def test_basic_cms_menu(self):
self.assertEqual(len(menu_pool.menus), 1)
with force_language("en"):
- response = self.client.get(self.get_pages_root()) # path = '/'
+ response = self.client.get(self.get_pages_root()) # path = '/'
self.assertEquals(response.status_code, 200)
request = self.get_request()
-
+
# test the cms menu class
menu = CMSMenu()
nodes = menu.get_nodes(request)
self.assertEqual(len(nodes), len(self.get_all_pages()))
-
+
def test_show_menu(self):
context = self.get_context()
- # test standard show_menu
+ # test standard show_menu
tpl = Template("{% load menu_tags %}{% show_menu %}")
tpl.render(context)
nodes = context['children']
@@ -110,10 +111,12 @@ def test_show_menu(self):
self.assertEqual(nodes[1].get_absolute_url(), self.get_page(4).get_absolute_url())
self.assertEqual(nodes[1].sibling, True)
self.assertEqual(nodes[1].selected, False)
-
+
+ @skipUnless(settings.DATABASES['default']['ENGINE'] == 'django.db.backends.sqlite3', 'transaction queries')
def test_show_menu_num_queries(self):
+ print settings.DATABASES['default']['ENGINE']
context = self.get_context()
- # test standard show_menu
+ # test standard show_menu
with self.assertNumQueries(5):
"""
The queries should be:
@@ -152,118 +155,118 @@ def test_only_active_tree(self):
context = self.get_context()
# test standard show_menu
tpl = Template("{% load menu_tags %}{% show_menu 0 100 0 100 %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['children']
self.assertEqual(len(nodes[1].children), 0)
self.assertEqual(len(nodes[0].children), 1)
self.assertEqual(len(nodes[0].children[0].children), 1)
context = self.get_context(path=self.get_page(4).get_absolute_url())
tpl = Template("{% load menu_tags %}{% show_menu 0 100 0 100 %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['children']
self.assertEqual(len(nodes[1].children), 1)
self.assertEqual(len(nodes[0].children), 0)
-
+
def test_only_one_active_level(self):
context = self.get_context()
- # test standard show_menu
+ # test standard show_menu
tpl = Template("{% load menu_tags %}{% show_menu 0 100 0 1 %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['children']
self.assertEqual(len(nodes[1].children), 0)
self.assertEqual(len(nodes[0].children), 1)
self.assertEqual(len(nodes[0].children[0].children), 0)
-
+
def test_only_level_zero(self):
context = self.get_context()
- # test standard show_menu
+ # test standard show_menu
tpl = Template("{% load menu_tags %}{% show_menu 0 0 0 0 %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['children']
for node in nodes:
self.assertEqual(len(node.children), 0)
-
-
+
+
def test_only_level_one(self):
context = self.get_context()
- # test standard show_menu
+ # test standard show_menu
tpl = Template("{% load menu_tags %}{% show_menu 1 1 100 100 %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['children']
self.assertEqual(len(nodes), len(self.get_level(1)))
for node in nodes:
self.assertEqual(len(node.children), 0)
-
-
+
+
def test_only_level_one_active(self):
context = self.get_context()
- # test standard show_menu
+ # test standard show_menu
tpl = Template("{% load menu_tags %}{% show_menu 1 1 0 100 %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['children']
self.assertEqual(len(nodes), 1)
self.assertEqual(nodes[0].descendant, True)
self.assertEqual(len(nodes[0].children), 0)
-
+
def test_level_zero_and_one(self):
context = self.get_context()
- # test standard show_menu
+ # test standard show_menu
tpl = Template("{% load menu_tags %}{% show_menu 0 1 100 100 %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['children']
self.assertEqual(len(nodes), 2)
for node in nodes:
self.assertEqual(len(node.children), 1)
-
+
def test_show_submenu(self):
context = self.get_context()
- # test standard show_menu
+ # test standard show_menu
tpl = Template("{% load menu_tags %}{% show_sub_menu %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['children']
self.assertEqual(nodes[0].descendant, True)
self.assertEqual(len(nodes), 1)
self.assertEqual(len(nodes[0].children), 1)
-
+
tpl = Template("{% load menu_tags %}{% show_sub_menu 1 %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['children']
self.assertEqual(len(nodes), 1)
self.assertEqual(len(nodes[0].children), 0)
-
+
def test_show_breadcrumb(self):
context = self.get_context(path=self.get_page(3).get_absolute_url())
tpl = Template("{% load menu_tags %}{% show_breadcrumb %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['ancestors']
self.assertEqual(len(nodes), 3)
tpl = Template("{% load menu_tags %}{% show_breadcrumb 1 %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['ancestors']
self.assertEqual(len(nodes), 2)
context = self.get_context()
tpl = Template("{% load menu_tags %}{% show_breadcrumb %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['ancestors']
self.assertEqual(len(nodes), 1)
tpl = Template("{% load menu_tags %}{% show_breadcrumb 1 %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['ancestors']
self.assertEqual(len(nodes), 0)
-
+
page1 = self.get_page(1)
page1.in_navigation = False
page1.save()
page2 = self.get_page(2)
context = self.get_context(path=page2.get_absolute_url())
tpl = Template("{% load menu_tags %}{% show_breadcrumb %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['ancestors']
self.assertEqual(len(nodes), 2)
self.assertEqual(nodes[0].get_absolute_url(), self.get_pages_root())
self.assertEqual(isinstance(nodes[0], NavigationNode), True)
self.assertEqual(nodes[1].get_absolute_url(), page2.get_absolute_url())
-
+
def test_language_chooser(self):
# test simple language chooser with default args
lang_settings = copy.deepcopy(settings.CMS_LANGUAGES)
@@ -289,7 +292,7 @@ def test_page_language_url(self):
tpl = Template("{%% load menu_tags %%}{%% page_language_url '%s' %%}" % settings.LANGUAGES[0][0])
url = tpl.render(context)
self.assertEqual(url, "%s" % path)
-
+
def test_show_menu_below_id(self):
page2 = self.get_page(2)
page2.reverse_id = "hello"
@@ -299,7 +302,7 @@ def test_show_menu_below_id(self):
page5 = self.get_page(5)
context = self.get_context(path=page5.get_absolute_url())
tpl = Template("{% load menu_tags %}{% show_menu_below_id 'hello' %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['children']
self.assertEqual(len(nodes), 1)
page3_url = self.get_page(3).get_absolute_url()
@@ -308,22 +311,22 @@ def test_show_menu_below_id(self):
page2.save()
context = self.get_context(path=page5.get_absolute_url())
tpl = Template("{% load menu_tags %}{% show_menu_below_id 'hello' %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['children']
self.assertEqual(len(nodes), 1)
self.assertEqual(nodes[0].get_absolute_url(), page3_url)
-
+
def test_unpublished(self):
page2 = self.get_page(2)
page2.published = False
page2.save()
context = self.get_context()
tpl = Template("{% load menu_tags %}{% show_menu %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['children']
self.assertEqual(len(nodes), 2)
self.assertEqual(len(nodes[0].children), 0)
-
+
def test_home_not_in_menu(self):
page1 = self.get_page(1)
page1.in_navigation = False
@@ -333,7 +336,7 @@ def test_home_not_in_menu(self):
page4.save()
context = self.get_context()
tpl = Template("{% load menu_tags %}{% show_menu 0 100 100 100 %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['children']
self.assertEqual(len(nodes), 1)
self.assertEqual(nodes[0].get_absolute_url(), self.get_page(2).get_absolute_url())
@@ -344,10 +347,10 @@ def test_home_not_in_menu(self):
menu_pool.clear(settings.SITE_ID)
context = self.get_context()
tpl = Template("{% load menu_tags %}{% show_menu 0 100 100 100 %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['children']
self.assertEqual(len(nodes), 2)
-
+
def test_show_submenu_from_non_menu_page(self):
"""
Here's the structure bit we're interested in:
@@ -362,40 +365,40 @@ def test_show_submenu_from_non_menu_page(self):
page6 = self.get_page(6)
context = self.get_context(page6.get_absolute_url())
tpl = Template("{% load menu_tags %}{% show_menu 1 100 0 1 %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['children']
number_of_p6_children = len(page6.children.filter(in_navigation=True))
self.assertEqual(len(nodes), number_of_p6_children)
-
+
page7 = self.get_page(7)
context = self.get_context(page7.get_absolute_url())
tpl = Template("{% load menu_tags %}{% show_menu 1 100 0 1 %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['children']
self.assertEqual(len(nodes), number_of_p6_children)
-
+
tpl = Template("{% load menu_tags %}{% show_menu 2 100 0 1 %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['children']
number_of_p7_children = len(page7.children.filter(in_navigation=True))
self.assertEqual(len(nodes), number_of_p7_children)
-
+
def test_show_breadcrumb_invisible(self):
# Must use the drafts to find the parent when calling create_page
parent = Page.objects.drafts().get(title_set__title='P3')
invisible_page = create_page("invisible", "nav_playground.html", "en",
parent=parent, published=True, in_navigation=False)
context = self.get_context(path=invisible_page.get_absolute_url())
tpl = Template("{% load menu_tags %}{% show_breadcrumb %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['ancestors']
self.assertEqual(len(nodes), 3)
tpl = Template("{% load menu_tags %}{% show_breadcrumb 0 'menu/breadcrumb.html' 1 %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['ancestors']
self.assertEqual(len(nodes), 3)
tpl = Template("{% load menu_tags %}{% show_breadcrumb 0 'menu/breadcrumb.html' 0 %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['ancestors']
self.assertEqual(len(nodes), 4)
@@ -416,20 +419,20 @@ def test_build_nodes_inner_for_worst_case_menu(self):
node3 = NavigationNode('Test3', '/test3/', 3, 4)
node4 = NavigationNode('Test4', '/test4/', 4, 5)
node5 = NavigationNode('Test5', '/test5/', 5, None)
-
+
menu_class_name = 'Test'
- nodes = [node1,node2,node3,node4,node5,]
+ nodes = [node1, node2, node3, node4, node5, ]
len_nodes = len(nodes)
-
+
final_list = _build_nodes_inner_for_one_menu(nodes, menu_class_name)
self.assertEqual(len(final_list), len_nodes)
-
+
self.assertEqual(node1.parent, node2)
self.assertEqual(node2.parent, node3)
self.assertEqual(node3.parent, node4)
self.assertEqual(node4.parent, node5)
self.assertEqual(node5.parent, None)
-
+
self.assertEqual(node1.children, [])
self.assertEqual(node2.children, [node1])
self.assertEqual(node3.children, [node2])
@@ -444,7 +447,7 @@ def test_build_nodes_inner_for_circular_menu(self):
Go nuts implementing it :)
'''
pass
-
+
def test_build_nodes_inner_for_broken_menu(self):
'''
Tests a broken menu tree (non-existing parent)
@@ -462,21 +465,21 @@ def test_build_nodes_inner_for_broken_menu(self):
node3 = NavigationNode('Test3', '/test3/', 3, 4)
node4 = NavigationNode('Test4', '/test4/', 4, 5)
node5 = NavigationNode('Test5', '/test5/', 5, None)
-
+
menu_class_name = 'Test'
- nodes = [node1,node2,node3,node4,node5,]
-
+ nodes = [node1, node2, node3, node4, node5, ]
+
final_list = _build_nodes_inner_for_one_menu(nodes, menu_class_name)
- self.assertEqual(len(final_list), 3)
+ self.assertEqual(len(final_list), 3)
self.assertFalse(node1 in final_list)
self.assertFalse(node2 in final_list)
-
+
self.assertEqual(node1.parent, None)
self.assertEqual(node2.parent, None)
self.assertEqual(node3.parent, node4)
self.assertEqual(node4.parent, node5)
self.assertEqual(node5.parent, None)
-
+
self.assertEqual(node1.children, [])
self.assertEqual(node2.children, [])
self.assertEqual(node3.children, [])
@@ -488,23 +491,23 @@ def test_utils_mark_descendants(self):
mark_descendants(tree_nodes)
for node in flat_nodes:
self.assertTrue(node.descendant, node)
-
+
def test_utils_find_selected(self):
tree_nodes, flat_nodes = self._get_nodes()
node = flat_nodes[0]
selected = find_selected(tree_nodes)
self.assertEqual(selected, node)
selected = find_selected([])
self.assertEqual(selected, None)
-
+
def test_utils_cut_levels(self):
tree_nodes, flat_nodes = self._get_nodes()
self.assertEqual(cut_levels(tree_nodes, 1), [flat_nodes[1]])
-
+
def test_empty_menu(self):
context = self.get_context()
tpl = Template("{% load menu_tags %}{% show_menu 0 100 100 100 %}")
- tpl.render(context)
+ tpl.render(context)
nodes = context['children']
self.assertEqual(len(nodes), 0)
@@ -537,13 +540,13 @@ class AdvancedSoftrootTests(SoftrootFixture, SettingsOverrideTestCase):
settings_overrides = {
'CMS_PERMISSION': False
}
-
+
def tearDown(self):
Page.objects.all().delete()
-
+
def get_page(self, name):
return Page.objects.public().get(title_set__slug=name)
-
+
def assertTreeQuality(self, a, b, *attrs):
"""
Checks that the node-lists a and b are the same for attrs.
@@ -552,14 +555,14 @@ def assertTreeQuality(self, a, b, *attrs):
"""
msg = '%r != %r with %r, %r' % (len(a), len(b), a, b)
self.assertEqual(len(a), len(b), msg)
- for n1, n2 in zip(a,b):
+ for n1, n2 in zip(a, b):
for attr in attrs:
a1 = getattr(n1, attr)
a2 = getattr(n2, attr)
msg = '%r != %r with %r, %r (%s)' % (a1, a2, n1, n2, attr)
self.assertEqual(a1, a2, msg)
self.assertTreeQuality(n1.children, n2.children)
-
+
def test_top_not_in_nav(self):
"""
top: not in navigation
@@ -579,7 +582,7 @@ def test_top_not_in_nav(self):
# root is NOT a soft root
context = self.get_context(aaa.get_absolute_url())
tpl = Template("{% load menu_tags %}{% show_menu 0 100 0 100 %}")
- tpl.render(context)
+ tpl.render(context)
hard_root = context['children']
# root IS a soft root
root = self.get_page('root')
@@ -588,11 +591,11 @@ def test_top_not_in_nav(self):
aaa = self.get_page('aaa')
context = self.get_context(aaa.get_absolute_url())
tpl = Template("{% load menu_tags %}{% show_menu 0 100 0 100 %}")
- tpl.render(context)
+ tpl.render(context)
soft_root = context['children']
# assert the two trees are equal in terms of 'level' and 'title'
self.assertTreeQuality(hard_root, soft_root, 'level', 'title')