diff --git a/cms_helper.py b/cms_helper.py index 06f5f39..f268fe6 100644 --- a/cms_helper.py +++ b/cms_helper.py @@ -83,6 +83,7 @@ HELPER_SETTINGS = { 'easy_thumbnails.processors.filters', ), 'FILE_UPLOAD_TEMP_DIR': mkdtemp(), + 'SITE_ID': 1 } if 'test' in sys.argv: HELPER_SETTINGS['INSTALLED_APPS'].append('django_nose') \ No newline at end of file diff --git a/djangocms_blog/admin.py b/djangocms_blog/admin.py index df54af0..ad7701e 100755 --- a/djangocms_blog/admin.py +++ b/djangocms_blog/admin.py @@ -7,7 +7,6 @@ from django.conf import settings from parler.admin import TranslatableAdmin from .models import Post, BlogCategory -from .settings import BLOG_USE_PLACEHOLDER, BLOG_MULTISITE class BlogCategoryAdmin(EnhancedModelAdminMixin, TranslatableAdmin): @@ -48,6 +47,7 @@ class PostAdmin(EnhancedModelAdminMixin, FrontendEditableAdmin, ] def get_fieldsets(self, request, obj=None): + from .settings import BLOG_USE_PLACEHOLDER, BLOG_MULTISITE fsets = deepcopy(self._fieldsets) if not BLOG_USE_PLACEHOLDER: fsets[0][1]['fields'].append('post_text') diff --git a/djangocms_blog/managers.py b/djangocms_blog/managers.py index 7f59b22..cc728cd 100644 --- a/djangocms_blog/managers.py +++ b/djangocms_blog/managers.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +import django from django.contrib.sites.models import Site from django.db.models import Q @@ -77,7 +78,7 @@ class GenericDateQuerySet(TranslatableQuerySet): publish_field = 'publish' def on_site(self): - return self.filter(Q(sites__isnull=True) | Q(sites=Site.objects.get_current())) + return self.filter(Q(sites__isnull=True) | Q(sites=Site.objects.get_current().pk)) def published(self): queryset = self.published_future() @@ -122,11 +123,10 @@ class GenericDateTaggedManager(TaggedFilterItem, TranslationManager): def get_queryset(self, *args, **kwargs): try: return super(GenericDateTaggedManager, self).get_queryset(*args, **kwargs) - except AttributeError: + except AttributeError: # pragma: no cover return super(GenericDateTaggedManager, self).get_query_set(*args, **kwargs) - - def get_query_set(self, *args, **kwargs): - return self.get_queryset(*args, **kwargs) + if django.VERSION < (1, 8): + get_query_set = get_queryset def published(self): return self.get_queryset().published() diff --git a/djangocms_blog/views.py b/djangocms_blog/views.py index 59c269c..bca3e13 100644 --- a/djangocms_blog/views.py +++ b/djangocms_blog/views.py @@ -18,7 +18,7 @@ class BaseBlogView(ViewUrlMixin): def get_queryset(self): language = get_language() - queryset = self.model._default_manager.active_translations(language_code=language) + queryset = self.model._default_manager.language(language_code=language) if not self.request.user.is_staff: queryset = queryset.published() return queryset.on_site() @@ -128,10 +128,7 @@ class CategoryEntriesView(BaseBlogView, ListView): @property def category(self): if not self._category: - language = get_language() - self._category = BlogCategory._default_manager.language(language).get( - translations__language_code=language, - translations__slug=self.kwargs['category']) + self._category = BlogCategory.objects.active_translations(get_language(), slug=self.kwargs['category']).last() return self._category def get_queryset(self): diff --git a/tests/__init__.py b/tests/__init__.py index daad139..16b18fc 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -2,13 +2,13 @@ """ Tests for `djangocms_blog` module. """ -from django.contrib.sites.models import Site import os from cms.utils.i18n import get_language_list from cmsplugin_filer_image.models import ThumbnailOption from django.conf import settings from django.contrib.auth import get_user_model +from django.contrib.sites.models import Site from django.core.files import File as DjangoFile from django.http import SimpleCookie from django.test import TestCase, RequestFactory @@ -17,8 +17,8 @@ from filer.models import File, Image from PIL import Image as PilImage, ImageDraw from six import StringIO -from djangocms_blog.models import BlogCategory, Post from djangocms_helper.utils import create_user +from djangocms_blog.models import BlogCategory, Post User = get_user_model() @@ -38,10 +38,13 @@ class BaseTest(TestCase): 'it': [ {'title': u'Primo post', 'abstract': u'

prima riga

', 'description': u'Questa รจ la descrizione', 'keywords': u'keyword1, keyword2', - 'text': u'Testo del post',}, + 'text': u'Testo del post'}, {'title': u'Secondo post', 'abstract': u'

prima riga del secondo post

', 'description': u'Descrizione del secondo post', 'keywords': u'keyword3, keyword4', 'text': u'Testo del secondo post'}, + {'title': u'Terzo post', 'abstract': u'

prima riga del terzo post

', + 'description': u'Descrizione del terzo post', 'keywords': u'keyword5, keyword6', + 'text': u'Testo del terzo post'}, ], 'en': [ {'title': u'First post', 'abstract': u'

first line

', @@ -49,7 +52,10 @@ class BaseTest(TestCase): 'text': u'Post text'}, {'title': u'Second post', 'abstract': u'

second post first line

', 'description': u'Second post description', 'keywords': u'keyword3, keyword4', - 'text': u'Second post text'} + 'text': u'Second post text'}, + {'title': u'Third post', 'abstract': u'

third post first line

', + 'description': u'third post description', 'keywords': u'keyword5, keyword6', + 'text': u'Third post text'} ] } @@ -59,19 +65,16 @@ class BaseTest(TestCase): cls.user = create_user('admin', 'admin@admin.com', 'admin', is_staff=True, is_superuser=True) cls.user_staff = create_user('staff', 'staff@admin.com', 'staff', is_staff=True) cls.user_normal = create_user('normal', 'normal@admin.com', 'normal') - cls.site_1 = Site.objects.create(domain='http://example1.com', name='example 1') + cls.site_1 = Site.objects.get(pk=1) cls.site_2 = Site.objects.create(domain='http://example2.com', name='example 2') def setUp(self): activate('en') super(BaseTest, self).setUp() - self.category_1 = BlogCategory.objects.create() - self.category_1.name = u'category 1' - self.category_1.save() - self.category_1.set_current_language('it') + self.category_1 = BlogCategory.objects.create(name=u'category 1') + self.category_1.set_current_language('it', initialize=True) self.category_1.name = u'categoria 1' self.category_1.save() - self.category_1.set_current_language('en') self.thumb_1 = ThumbnailOption.objects.create( name='base', width=100, height=100, crop=True, upscale=False ) @@ -88,18 +91,27 @@ class BaseTest(TestCase): original_filename=self.image_name, file=file_obj) - def _get_post(self, data, post=None, lang='en'): + def _get_post(self, data, post=None, lang='en', sites=None): if not post: - post = Post() - post.set_current_language(lang) - post.author = self.user - post.title = data['title'] - post.abstract = data['abstract'] - post.meta_description = data['description'] - post.meta_keywords = data['keywords'] - post.save() + post_data = { + 'author': self.user, + 'title': data['title'], + 'abstract': data['abstract'], + 'meta_description': data['description'], + 'meta_keywords': data['keywords'], + } + post = Post.objects.create(**post_data) + else: + post.set_current_language(lang) + post.title = data['title'] + post.abstract = data['abstract'] + post.meta_description = data['description'] + post.meta_keywords = data['keywords'] + post.save() post.categories.add(self.category_1) - post.save() + if sites: + for site in sites: + post.sites.add(site) return post @classmethod @@ -107,6 +119,8 @@ class BaseTest(TestCase): User.objects.all().delete() def tearDown(self): + for post in Post.objects.all(): + post.delete() os.remove(self.filename) for f in File.objects.all(): f.delete() @@ -149,17 +163,16 @@ class BaseTest(TestCase): mid.process_request(request) return request - def get_posts(self): - post1 = self._get_post(self.data['en'][0]) + def get_posts(self, sites=None): + post1 = self._get_post(self.data['en'][0], sites=sites) post1 = self._get_post(self.data['it'][0], post1, 'it') post1.publish = True post1.main_image = self.img post1.save() - post1.set_current_language('en') - post2 = self._get_post(self.data['en'][1]) + post2 = self._get_post(self.data['en'][1], sites=sites) post2 = self._get_post(self.data['it'][1], post2, 'it') - post2.set_current_language('en') post2.main_image = self.img + post2.save() return post1, post2 diff --git a/tests/test_models.py b/tests/test_models.py index 45296fd..8a6948f 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -2,9 +2,11 @@ from cms.api import add_plugin from cms.utils.copy_plugins import copy_plugins_to from cms.utils.plugins import downcast_plugins +from django.contrib import admin from django.contrib.sites.models import Site from django.core.urlresolvers import reverse from django.utils.timezone import now +from django.utils.translation import get_language, override import parler from taggit.models import Tag @@ -15,6 +17,33 @@ from djangocms_blog import settings from . import BaseTest +class AdminTest(BaseTest): + + def test_admin_fieldsets(self): + request = self.get_page_request('/', self.user_staff, r'/en/blog/', edit=False) + post_admin = admin.site._registry[Post] + + settings.BLOG_USE_PLACEHOLDER = True + fsets = post_admin.get_fieldsets(request) + self.assertFalse('post_text' in fsets[0][1]['fields']) + settings.BLOG_USE_PLACEHOLDER = False + fsets = post_admin.get_fieldsets(request) + self.assertTrue('post_text' in fsets[0][1]['fields']) + settings.BLOG_USE_PLACEHOLDER = True + + settings.BLOG_MULTISITE = True + fsets = post_admin.get_fieldsets(request) + self.assertTrue('sites' in fsets[1][1]['fields'][0]) + settings.BLOG_MULTISITE = False + fsets = post_admin.get_fieldsets(request) + self.assertFalse('sites' in fsets[1][1]['fields'][0]) + settings.BLOG_MULTISITE = True + + request = self.get_page_request('/', self.user, r'/en/blog/', edit=False) + fsets = post_admin.get_fieldsets(request) + self.assertTrue('author' in fsets[1][1]['fields'][0]) + + class ModelsTest(BaseTest): def test_model_attributes(self): @@ -37,23 +66,26 @@ class ModelsTest(BaseTest): self.assertNotEqual(meta_it.title, meta_en.title) self.assertEqual(meta_it.description, post.meta_description) - post.set_current_language('en') - kwargs = {'year': post.date_published.year, - 'month': post.date_published.month, - 'day': post.date_published.day, - 'slug': post.safe_translation_getter('slug', any_language=True)} - url_en = reverse('djangocms_blog:post-detail', kwargs=kwargs) - self.assertEqual(url_en, post.get_absolute_url()) - post.set_current_language('it') - kwargs = {'year': post.date_published.year, - 'month': post.date_published.month, - 'day': post.date_published.day, - 'slug': post.safe_translation_getter('slug', any_language=True)} - url_it = reverse('djangocms_blog:post-detail', kwargs=kwargs) - self.assertEqual(url_it, post.get_absolute_url()) - self.assertNotEqual(url_it, url_en) + with override('en'): + post.set_current_language(get_language()) + kwargs = {'year': post.date_published.year, + 'month': '%02d' % post.date_published.month, + 'day': '%02d' % post.date_published.day, + 'slug': post.safe_translation_getter('slug', any_language=get_language())} + url_en = reverse('djangocms_blog:post-detail', kwargs=kwargs) + self.assertEqual(url_en, post.get_absolute_url()) - self.assertEqual(post.get_full_url(), 'http://example.com%s' % url_it) + with override('it'): + post.set_current_language(get_language()) + kwargs = {'year': post.date_published.year, + 'month': '%02d' % post.date_published.month, + 'day': '%02d' % post.date_published.day, + 'slug': post.safe_translation_getter('slug', any_language=get_language())} + url_it = reverse('djangocms_blog:post-detail', kwargs=kwargs) + self.assertEqual(url_it, post.get_absolute_url()) + self.assertNotEqual(url_it, url_en) + + self.assertEqual(post.get_full_url(), 'http://example.com%s' % url_it) self.assertEqual(post.get_image_full_url(), 'http://example.com%s' % post.main_image.url) self.assertEqual(post.thumbnail_options(), settings.BLOG_IMAGE_THUMBNAIL_SIZE) @@ -213,3 +245,17 @@ class ModelsTest(BaseTest): copy_plugins_to(plugins, post2.content) new = downcast_plugins(post2.content.cmsplugin_set.all()) self.assertEqual(set(new[0].authors.all()), set([self.user])) + + def test_multisite(self): + with override('en'): + post1 = self._get_post(self.data['en'][0], sites=(self.site_1,)) + post2 = self._get_post(self.data['en'][1], sites=(self.site_2,)) + post3 = self._get_post(self.data['en'][2], sites=(self.site_2, self.site_1)) + + self.assertEqual(len(Post.objects.all()), 3) + with self.settings(**{'SITE_ID': self.site_1.pk}): + self.assertEqual(len(Post.objects.all().on_site()), 2) + self.assertEqual(set(list(Post.objects.all().on_site())), set([post1, post3])) + with self.settings(**{'SITE_ID': self.site_2.pk}): + self.assertEqual(len(Post.objects.all().on_site()), 2) + self.assertEqual(set(list(Post.objects.all().on_site())), set([post2, post3])) diff --git a/tests/test_views.py b/tests/test_views.py index 9cbec46..69621b0 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -3,7 +3,8 @@ from django.contrib.auth.models import AnonymousUser from django.http import Http404 from django.utils.translation import activate from django.utils.timezone import now -from djangocms_blog.models import Post +from parler.utils.context import switch_language +from djangocms_blog.models import Post, BlogCategory from djangocms_blog.feeds import LatestEntriesFeed, TagFeed from djangocms_blog.sitemaps import BlogSitemap from djangocms_blog.views import (PostListView, PostDetailView, @@ -54,34 +55,33 @@ class ViewTest(BaseTest): page1, page2 = self.get_pages() post1, post2 = self.get_posts() - request = self.get_page_request(page1, AnonymousUser(), r'/en/blog/', edit=False) - activate('en') - view_obj = PostDetailView() - view_obj.request = request + with switch_language(post1, 'en'): + request = self.get_page_request(page1, AnonymousUser(), r'/en/blog/', edit=False) + view_obj = PostDetailView() + view_obj.request = request - with self.assertRaises(Http404): - view_obj.kwargs = {'slug': 'not-existing'} + with self.assertRaises(Http404): + view_obj.kwargs = {'slug': 'not-existing'} + post_obj = view_obj.get_object() + + view_obj.kwargs = {'slug': post1.slug} post_obj = view_obj.get_object() + self.assertEqual(post_obj, post1) + self.assertEqual(post_obj.language_code, 'en') - view_obj.kwargs = {'slug': post1.slug} - post_obj = view_obj.get_object() - self.assertEqual(post_obj, post1) - self.assertEqual(post_obj.language_code, 'en') + with switch_language(post1, 'it'): + request = self.get_page_request(page1, AnonymousUser(), r'/it/blog/', lang_code='it', edit=False) + view_obj.request = request + view_obj.kwargs = {'slug': post1.slug} + post_obj = view_obj.get_object() + self.assertEqual(post_obj, post1) + self.assertEqual(post_obj.language_code, 'it') - request = self.get_page_request(page1, AnonymousUser(), r'/it/blog/', lang_code='it', edit=False) - activate('it') - post1.set_current_language('it') - view_obj.request = request - view_obj.kwargs = {'slug': post1.slug} - post_obj = view_obj.get_object() - self.assertEqual(post_obj, post1) - self.assertEqual(post_obj.language_code, 'it') - - view_obj.object = post_obj - context = view_obj.get_context_data() - self.assertEqual(context['post'], post1) - self.assertEqual(context['post'].language_code, 'it') - self.assertTrue(context['meta']) + view_obj.object = post_obj + context = view_obj.get_context_data() + self.assertEqual(context['post'], post1) + self.assertEqual(context['post'].language_code, 'it') + self.assertTrue(context['meta']) def test_post_archive_view(self): page1, page2 = self.get_pages()