diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..551200814a66d2927861a63f4b5f52272a8a5ea8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.pyc +django_newsbox.egg-info +*~ +.tox +tests/mydatabase diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000000000000000000000000000000000000..bf4584eda8aaf2be0cc09e5bc8b57cb1221a0b3f --- /dev/null +++ b/AUTHORS @@ -0,0 +1,3 @@ +* Webu (webu.coop) https://github.com/webu +* Dylann CORDEL <d.cordel@webu.coop> https://github.com/dylannCordel +* Olivier Le Brouster <o.lebrouster@webu.coop> diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..4c36e0a17a450a8a8083aed25fb9a25e0f22b887 --- /dev/null +++ b/LICENSE @@ -0,0 +1,25 @@ +.===================================================================. +|| Copyright (c) 2013, Webu || +|| Currently under Beerware License || +|| ___ || +|| .' '. || +|| / \ oOoOo || +|| | | ,==||||| || +|| \ / _|| ||||| || +|| '.___.' _.-'^|| ||||| || +|| __/_______.-' '==HHHHH || +|| _.-'` / """"" || +|| .-' / oOoOo || +|| `-._ / ,==||||| || +|| '-/._|| ||||| || +|| / ^|| ||||| || +|| / '==HHHHH || +|| /________""""" || +|| `\ `\ || +|| \ `\ / || +|| \ `\/ || +|| / || +|| / || +|| jgs /_____ || +|| || +'===================================================================' diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000000000000000000000000000000000000..4d32fdfe2147b41762b52c45d0e2c241e06768ee --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,12 @@ +include AUTHORS +include LICENSE +include MANIFEST.in +include README.md +include ROADMAP.md +include TESTING.md +recursive-include tests * +recursive-include test_requirements * +recursive-include newsbox/templates * +recursive-include newsbox/locale * +recursive-include newsbox_cms/templates * +recursive-include newsbox_cms/locale * diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..2c1169702a277f854cc2526dcc27ba435c53a56a --- /dev/null +++ b/README.md @@ -0,0 +1,51 @@ +# Django News Box + +This django app is a toolbox to easily setup news in your projects. + +## Features + + * easy custom fields + * optional SEO fields + * optional publication period + * optional i18n support via hvad + * optional django-cms support + +## Installation + +## django CMS integration + +### models.py + + class News(NewsboxCMSBase, NewsboxSEOBase): + + class Meta: + newsbox_detail_url_name = "news_detail" # optional + +### cms_app.py + + class NewsApphook(CMSApp): + name = _("News") + urls = ["myproject.news_urls"] + + apphook_pool.register(NewsApphook) + + +### news_urls.py + + from django.conf.urls import patterns, url + from newsbox.views import NewsboxDetailView + from .models import News + + urlpatterns = patterns( + '', + url( + r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/(?P<slug>[0-9a-zA-Z_-]+)/$', + NewsboxDetailView.as_view( + template_name="myproject/news_detail.html", + model=News,), + name='news_detail'), + ) + +### cms_plugin.py + +TODO diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000000000000000000000000000000000000..53a76513d9e174b5ccfc3834106f5129f4b9bf30 --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,51 @@ +# Feuile de route du développement de l'application + +## Classes abstraites + +* [OK] News "basiques" +* [OK] News qui se périment dans le temps +* [OK] News optimisée pour le SEO +* [TODO] News avec auteur +* [TODO] : internationnaliser les contenus utiles (hvad ?) + +## Gestion des droits + +[TODO] + +## Tests unitaires + +[TODO] + +## Interface d'administration pour gérer les actualités + +* lien directe pour publier / dépublier une news +* [TODO] lien pour la gestion du multi langue comme pour les pages +* [TODO] à voir si c'est possible : lien d'affichage sur le site ? + +## Template basique pour afficher la liste des news + +TODO + +## Template basique pour afficher le détail d'une news + +TODO + +## Intégration à Django-CMS + +### Plugin pour ajouter les news sur les pages + +TODO + +### Édition / ajout front-end des news + +TODO + +## Intégration des catégories + +TODO ? Utile de l'intégrer plutot que de le laisser +à la discrétion de l'utilisateur ? + +## Questions : + +* liaison avec l'objet Site ? +* django-catégories ? à la discrétion de l'utilisateur ? diff --git a/TESTING.md b/TESTING.md new file mode 100644 index 0000000000000000000000000000000000000000..d5e228b8ababd3706569e96a938744bc4e04b46d --- /dev/null +++ b/TESTING.md @@ -0,0 +1,25 @@ +Testing newsbox and newsbox_cms +================================= + +Testing in multiple environment +------------------------------- + +It's the better way to test this application. You will test it with many +versions of Python, Django and Django CMS for newsbox_cms. + +## Requirements + +First, you need to install tox:: + + pip install "tox>=1.6,<1.8" + + + +Testing in your specific environnement +-------------------------------------- + +If you don't care about tests this app in other environnements than yours, you +can only execute runtests.sh from "tests" directory. Newsbox will be tested +with your versions of python, Django, installed python modules etc. +It can be usefull if you run a very specific environnement which is not tested +with our tox configurations. diff --git a/newsbox/__init__.py b/newsbox/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1c06be72c87a445749cca3d92df4f87e3311f7dd --- /dev/null +++ b/newsbox/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +__version__="0.1.0" diff --git a/newsbox/admin.py b/newsbox/admin.py new file mode 100644 index 0000000000000000000000000000000000000000..b76dc1f66075e57e9be7a0ae3ee84757ec5d5064 --- /dev/null +++ b/newsbox/admin.py @@ -0,0 +1,325 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +import copy + +from django.conf.urls import url, patterns +from django.contrib import messages, admin +from django.contrib.admin.models import LogEntry, CHANGE +from django.contrib.admin.templatetags.admin_static import static +from django.contrib.contenttypes.models import ContentType +from django.core.urlresolvers import reverse +from django.http import HttpResponseForbidden, HttpResponseRedirect +from django.shortcuts import get_object_or_404 +from django.utils.translation import ugettext_lazy as _, ungettext_lazy +from django.utils import six + + +def get_fieldset_by_field(name, fieldsets): + """ + Return fieldset containing a field given by name + """ + for fieldset in fieldsets: + options = fieldset[1] + if name in options.get('fields', {}): + return fieldset + return None + + +def remove_field_from_fieldsets(name, fieldsets, remove_empty_fieldset=True): + """ + Remove a field from all fieldset in fieldsets. + """ + while True: + fieldset = get_fieldset_by_field(name, fieldsets) + if fieldset: + fieldset[1]['fields'].remove(name) + if remove_empty_fieldset and len(fieldset[1]['fields']) == 0: + fieldsets.remove(fieldset) + else: + break + + +def add_fields_to_fieldset( + fields, + fieldsets, + after_field=None, + same_fieldset_as=None, + default_fieldset_name=None, + default_fieldset_classes=None, + default_fieldset_position=None, + replace_existing_field=False, + remove_empty_fieldset=False, +): + """ + Add fields in a fieldsets attribute + + Try to find a fieldset containing same_fieldset_as value in fields. If not + found a new fieldset is created with name `default_fieldset_name`, position + `default_fieldset_position` and classes `default_fieldset_classes`. + + Fields are inserted just after after_field. If not found, they are inserted + at the end. + + If replace_existing_field is True, existing fields in fieldsets with same + name are removed. + + """ + if same_fieldset_as is None and after_field: + same_fieldset_as = after_field + + # Find fieldset + fieldset = get_fieldset_by_field(same_fieldset_as, fieldsets) + + if fieldset is None: + fieldset = (default_fieldset_name, { + 'fields': [], + 'classes': default_fieldset_classes, + }) + allready_inserted = False + else: + allready_inserted = True + + # Insert fields + index = None + if after_field: + index = fieldset[1]['fields'].index(after_field) + 1 + + index = index or len(fieldset[1]['fields']) + for field in fields: + if replace_existing_field: + remove_field_from_fieldsets( + field, fieldsets, + remove_empty_fieldset=remove_empty_fieldset) + elif get_fieldset_by_field(field, fieldsets) is not None: + continue + + fieldset[1]['fields'].insert(index, field) + index += 1 + + # Insert fieldset if needed. + if not allready_inserted and len(fieldset[1]['fields']) > 0: + if default_fieldset_position is not None: + fieldsets.insert(default_fieldset_position, fieldset) + else: + fieldsets.append(fieldset) + + +def changestatus_link(obj): + if obj.newsbox_published: + title = _('Unpublish this %s') % six.text_type( + obj._meta.verbose_name) + icon_url = static('admin/img/icon-yes.gif') + else: + title = _('Publish this %s') % six.text_type( + obj._meta.verbose_name) + icon_url = static('admin/img/icon-no.gif') + return '<a href="%s" title="%s"><img src="%s" alt="%s" /></a>' % ( + reverse('admin:admin_newsbox_%s_change_status' % ( + six.text_type(obj._meta.verbose_name)), + args=[obj.pk, ]), + title, icon_url, obj.newsbox_published) + + +changestatus_link.allow_tags = True +changestatus_link.admin_order_field = 'newsbox_published' +changestatus_link.short_description = _('published') + + +class NewsboxBaseAdmin(admin.ModelAdmin): + + list_filter = ('newsbox_publication_start_date', 'newsbox_published', ) + list_display = ['get_newsbox_title', 'newsbox_date', + 'get_newsbox_slug', changestatus_link] + list_display_links = ('get_newsbox_title',) + fieldsets = [ + (None, { + 'fields': ['newsbox_title', 'newsbox_slug', 'newsbox_date', 'newsbox_published', ], }), + (_('Content'), { + 'fields': ['newsbox_summary', 'newsbox_body'], }), ] + actions = ['publish', 'unpublish'] + save_as = True + + def __init__(self, *args, **kwargs): + # This is a workaround for prepopulated_fields with hvad + self.prepopulated_fields = {"newsbox_slug": ("newsbox_title",)} + super(NewsboxBaseAdmin, self).__init__(*args, **kwargs) + + def get_fieldsets(self, request, obj=None): + """ + Prevent anoying modification of fieldsets class attribute. + """ + fieldsets = super(NewsboxBaseAdmin, self).get_fieldsets(request, obj) + return copy.deepcopy(fieldsets) + + def get_newsbox_title(self, obj): + return obj.newsbox_title + get_newsbox_title.short_description = _('Title') + + def get_newsbox_slug(self, obj): + return obj.newsbox_slug + get_newsbox_slug.short_description = _('Slug') + + def get_urls(self): + urls = super(NewsboxBaseAdmin, self).get_urls() + my_urls = patterns('', url( + r'^([0-9]+)/change-status/$', + self.admin_site.admin_view(self.change_status), + name='admin_newsbox_%s_change_status' % ( + six.text_type(self.model._meta.verbose_name),))) + return my_urls + urls + + def change_status(self, request, news_id): + """ + Switch the status of a news + """ + + news = get_object_or_404(self.model, pk=news_id) + if not news.has_publish_permission(request): + return HttpResponseForbidden( + _('You do not have permission to publish this %s') + % (six.text_type(self.model._meta.verbose_name),)) + + news.newsbox_published = not news.newsbox_published + news.save() + if news.newsbox_published: + messages.info( + request, + _( + 'The %(objtype)s "%(objtitle)s" was ' + 'successfully published' + ) % { + 'objtype': six.text_type(self.model._meta.verbose_name), + 'objtitle': news} + ) + else: + messages.info( + request, + _( + 'The %(objtype)s "%(objtitle)s" was ' + 'successfully unpublished' + ) % { + 'objtype': six.text_type(self.model._meta.verbose_name), + 'objtitle': news} + ) + LogEntry.objects.log_action( + user_id=request.user.id, + content_type_id=ContentType.objects.get_for_model(self.model).pk, + object_id=news_id, + object_repr=six.text_type(news), + action_flag=CHANGE, + ) + return HttpResponseRedirect('../../') + + def publish(self, request, queryset): + """ + Marks selected news items as published + """ + ok = 0 + for news in queryset: + if news.newsbox_published: + continue + + if not news.has_publish_permission(request): + messages.error( + request, + _( + 'You do not have permission to publish the ' + '%(objtype)s "%(objtitle)s"' + ) % { + 'objtype': six.text_type(self.model._meta.verbose_name), + 'objtitle': news + } + ) + continue + news.newsbox_published = True + news.save() + ok += 1 + + messages.success(request, ungettext_lazy( + '%(nb)d %(objtype)s was published', + '%(nb)d %(objtype)s were published', + ok) % {'nb': ok, 'objtype': self.model._meta.verbose_name}) + publish.short_description = _('Publish selected %(verbose_name_plural)s') + + def unpublish(self, request, queryset): + """ + Marks selected news items as unpublished + """ + ok = 0 + for news in queryset: + if not news.newsbox_published: + continue + + if not news.has_publish_permission(request): + messages.error( + request, + _( + 'You do not have permission to unpublish the ' + '%(objtype)s "%(objtitle)s"' + ) % { + 'objtype': six.text_type(self.model._meta.verbose_name), + 'objtitle': news + } + ) + continue + news.newsbox_published = False + news.save() + ok += 1 + + messages.success(request, ungettext_lazy( + '%(nb)d %(objtype)s was unpublished', + '%(nb)d %(objtype)s were unpublished', + ok) % { + 'nb': ok, + 'objtype': self.model._meta.verbose_name, + } + ) + unpublish.short_description = _( + 'Unpublish selected %(verbose_name_plural)s') + +class NewsboxAdmin(NewsboxBaseAdmin): + pass + + +class NewsboxExpiredAdmin(NewsboxBaseAdmin): + + def get_fieldsets(self, request, obj=None): + fieldsets = super(NewsboxExpiredAdmin, self).get_fieldsets(request, obj) + + remove_field_from_fieldsets('newsbox_published', fieldsets) + add_fields_to_fieldset( + ['newsbox_published', + 'newsbox_publication_start_date', + 'newsbox_publication_end_date', ], + fieldsets, + default_fieldset_name=_('Publication'), + default_fieldset_position=1) + + return fieldsets + + def get_list_display(self, request): + list_display = super(NewsboxExpiredAdmin, self).get_list_display(request) + + list_display = list_display[:2] +\ + ['newsbox_publication_end_date',] + list_display[2:] + return list_display + +class NewsboxSEOAdmin(NewsboxBaseAdmin): + + def get_fieldsets(self, request, obj=None): + fieldsets = super(NewsboxSEOAdmin, self).get_fieldsets(request, obj) + + add_fields_to_fieldset( + ['newsbox_indexed', + 'newsbox_meta_description', + 'newsbox_meta_keywords', ], + fieldsets, + default_fieldset_name=_('SEO Settings'), + default_fieldset_classes=('collapse',), + ) + + return fieldsets + + def get_list_display(self, request): + list_display = super(NewsboxSEOAdmin, self).get_list_display(request) + return list_display diff --git a/newsbox/locale/fr/LC_MESSAGES/django.mo b/newsbox/locale/fr/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..568c03c52430e6f7dc02de3913e9bac2a42b084f Binary files /dev/null and b/newsbox/locale/fr/LC_MESSAGES/django.mo differ diff --git a/newsbox/locale/fr/LC_MESSAGES/django.po b/newsbox/locale/fr/LC_MESSAGES/django.po new file mode 100644 index 0000000000000000000000000000000000000000..ec7afe005fc914ca435123be17e23486c1c22a14 --- /dev/null +++ b/newsbox/locale/fr/LC_MESSAGES/django.po @@ -0,0 +1,270 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-01-18 15:31+0100\n" +"PO-Revision-Date: 2014-01-18 15:26+0100\n" +"Last-Translator: Dylann Cordel <cordel.d@free.fr>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: admin.py:28 +msgid "translations" +msgstr "traductions" + +#: admin.py:53 +msgid "edit" +msgstr "modifier" + +#: admin.py:56 models.py:72 +msgid "title" +msgstr "titre" + +#: admin.py:61 +#, python-format +msgid "Unpublish this %s" +msgstr "Dépublier cette %s" + +#: admin.py:65 +#, python-format +msgid "Publish this %s" +msgstr "Publier cette %s" + +#: admin.py:75 models.py:169 +msgid "published" +msgstr "publiée" + +#: admin.py:86 +msgid "Content" +msgstr "Contenu" + +#: admin.py:100 newsboxcms/models.py:14 +msgid "Title" +msgstr "Titre" + +#: admin.py:104 +msgid "Slug" +msgstr "Slug" + +#: admin.py:123 +#, python-format +msgid "You do not have permission to publish this %s" +msgstr "Vous n'avez pas la permission de publier cette %s" + +#: admin.py:129 +#, python-format +msgid "The %(objtype)s \"%(objtitle)s\" was successfully published" +msgstr "Cette %(objtype)s \"%(objtitle)s\" a été publiée avec succès" + +#: admin.py:135 +#, python-format +msgid "The %(objtype)s \"%(objtitle)s\" was successfully unpublished" +msgstr "Cette %(objtype)s \"%(objtitle)s\" a été dépubliée avec succès" + +#: admin.py:160 +#, python-format +msgid "You do not have permission to publish the %(objtype)s \"%(objtitle)s\"" +msgstr "" +"Vous n'avez pas la permission de publier cette %(objtype)s \"%(objtitle)s\"" + +#: admin.py:172 +#, python-format +msgid "%(nb)d %(objtype)s was published" +msgid_plural "%(nb)d %(objtype)s were published" +msgstr[0] "%(nb)d %(objtype)s a été dépubliée avec succès" +msgstr[1] "%(nb)d %(objtype)s ont été dépubliées avec succès" + +#: admin.py:175 +#, python-format +msgid "Publish selected %(verbose_name_plural)s" +msgstr "Publier les %(verbose_name_plural)s sélectionnées" + +#: admin.py:188 +#, python-format +msgid "" +"You do not have permission to unpublish the %(objtype)s \"%(objtitle)s\"" +msgstr "" +"Vous n'avez pas la permission de dépublier cette %(objtype)s \"%(objtitle)s\"" + +#: admin.py:200 +#, python-format +msgid "%(nb)d %(objtype)s was unpublished" +msgid_plural "%(nb)d %(objtype)s were unpublished" +msgstr[0] "%(nb)d %(objtype)s a été dépubliée avec succès" +msgstr[1] "%(nb)d %(objtype)s ont été dépubliées avec succès" + +#: admin.py:208 +#, python-format +msgid "Unpublish selected %(verbose_name_plural)s" +msgstr "Dépublier les %(verbose_name_plural)s sélectionnées" + +#: admin.py:237 +msgid "Publication" +msgstr "Publication" + +#: admin.py:244 +msgid "SEO Settings" +msgstr "Options de référencement" + +#: models.py:75 +msgid "slug" +msgstr "slug" + +#: models.py:77 +msgid "The part of the title that is used in the URL" +msgstr "La partie du titre utilisée dans l'URL" + +#: models.py:85 models.py:95 +msgid "summary" +msgstr "résumé" + +#: models.py:89 models.py:97 +msgid "body" +msgstr "corps" + +#: models.py:104 +msgid "meta description" +msgstr "méta description" + +#: models.py:107 +msgid "meta keywords" +msgstr "méta mots clés" + +#: models.py:147 +msgid "creation date" +msgstr "date de création" + +#: models.py:151 +msgid "last update date" +msgstr "date de dernière modification" + +#: models.py:157 +msgid "date" +msgstr "date" + +#: models.py:162 +msgid "publication start date" +msgstr "date de début de publication" + +#: models.py:165 +msgid "" +"When the news should go live. Status must be \"Published\" for news to go " +"live." +msgstr "" +"Date à laquelle l'actualité sera visible. Le statut doit être \"publié\" " +"pour que l'actualité soit visible." + +#: models.py:178 +#, python-format +msgid "News n° %s" +msgstr "Actualité n° %s" + +#: models.py:236 models.py:237 +msgid "news" +msgstr "actualité" + +#: models.py:252 +msgid "publication end date" +msgstr "date de fin de publication" + +#: models.py:255 +msgid "When to expire the news.Leave empty to never expire." +msgstr "" +"Date à laquelle l'actualité ne sera plus visible. Laisser vide pour qu'elle " +"n'expire jamais." + +#: models.py:269 +msgid "indexed" +msgstr "indéxée" + +#: models.py:272 +msgid "An unindexed news will not be indexed by search engines." +msgstr "" +"Une actualité non indéxée ne sera jamais indéxée par les moteurs de recherche" + +#: views.py:21 newsboxcms/cms_plugins.py:21 +msgid "The choosen news type to display is invalid" +msgstr "Le type d'actualité à afficher choisi est invalide" + +#: newsboxcms/cms_plugins.py:10 +msgid "News list" +msgstr "Liste d'actualité" + +#: newsboxcms/models.py:11 +msgid "News type to display" +msgstr "Type d'actualité à afficher" + +#: newsboxcms/models.py:16 +msgid "Title to display before the list" +msgstr "Titre à afficher avant la liste" + +#: newsboxcms/models.py:18 +msgid "Number of news" +msgstr "Nombre d'actualité" + +#: newsboxcms/models.py:20 +msgid "Number of news to display. \"0\" allow you to display ALL news" +msgstr "" +"Nombre d'actualité à afficher. \"0\" permet d'afficher TOUTES les actualités " +"(sans pagination)" + +#: newsboxcms/models.py:23 +msgid "Display a pager" +msgstr "Affiche une pagination" + +#: newsboxcms/models.py:29 +#, fuzzy, python-format +msgid "Display of a news" +msgid_plural "Display of %(nb)d news" +msgstr[0] "Affichage de toutes les actualités" +msgstr[1] "Affichage de toutes les actualités" + +#: newsboxcms/models.py:33 +msgid "Display of all news" +msgstr "Affichage de toutes les actualités" + +#: newsboxcms/templates/newsboxcms/list-cms.html:11 +#: templates/newsbox/list.html:38 +msgid "Read more" +msgstr "Lire la suite" + +#: templates/newsbox/list.html:53 +msgid "Previous news" +msgstr "Actualités précédentes" + +#: templates/newsbox/list.html:57 +#, python-format +msgid "Page %(number)s on %(total)s" +msgstr "Page %(number)s sur %(total)s" + +#: templates/newsbox/list.html:61 +msgid "Next news" +msgstr "Actualités suivantes" + +#: templates/newsbox/list.html:65 +msgid "See all news" +msgstr "Voir toutes les actualités" + +#~ msgid "" +#~ "\n" +#~ " Page %(number)s on %(total)s\n" +#~ " " +#~ msgstr "" +#~ "\n" +#~ " Page %(number)s sur %(total)s\n" +#~ " " + +#, fuzzy +#~ msgid "%d %s was published" +#~ msgid_plural "%d %s were published" +#~ msgstr[0] "publiée" +#~ msgstr[1] "publiée" diff --git a/newsbox/migrations/__init__.py b/newsbox/migrations/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/newsbox/models.py b/newsbox/models.py new file mode 100644 index 0000000000000000000000000000000000000000..10ef5d1d78faa0b859e88543cf5c9ef5432e0050 --- /dev/null +++ b/newsbox/models.py @@ -0,0 +1,268 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +import sys +from datetime import datetime + +from django.core.urlresolvers import reverse +from django.db import models +from django.utils.timezone import utc +from django.utils.translation import ugettext_lazy as _ +from django.utils.encoding import python_2_unicode_compatible +from django.utils import six + +newsbox_models = [] + +def newsbox_mcls_processor(mcls, class_name, class_bases, class_attrs, base, newsbox_opts): + class_attrs['newsbox_title'] = models.CharField( + verbose_name=_('title'), + max_length=255) + class_attrs['newsbox_slug'] = models.SlugField( + verbose_name=_('slug'), + unique_for_date='newsbox_date', + help_text=_('The part of the title that is used in the URL')) + class_attrs['newsbox_summary'] = models.TextField( + verbose_name=_('summary')) + class_attrs['newsbox_body'] = models.TextField( + verbose_name=_('body'), + null=False, blank=True) + newsbox_opts['trans_fieldnames']+=[ + 'newsbox_title', 'newsbox_slug', + 'newsbox_summary', 'newsbox_body'] + +def newsboxseo_mcls_processor(mcls, class_name, class_bases, class_attrs, base, newsbox_opts): + class_attrs['newsbox_meta_description'] = models.TextField( + verbose_name=_('meta description'), + max_length=255, blank=True, null=True) + class_attrs['newsbox_meta_keywords'] = models.CharField( + verbose_name=_('meta keywords'), + max_length=255, blank=True, null=True) + + newsbox_opts['trans_fieldnames']+=[ + 'newsbox_meta_description', 'newsbox_meta_keywords'] + +class NewsboxManager(models.Manager): + """ + Filter published news + """ + + def published(self): + now = datetime.utcnow().replace(tzinfo=utc) + query_set = super(NewsboxManager, self).get_query_set().filter( + # Only published News + models.Q(newsbox_published=True), + ).exclude( + # exclude news with publication start date in the future + models.Q(newsbox_publication_start_date__gt=now) + ) + + if issubclass(self.model, NewsboxExpiredBase): + query_set = query_set.exclude( + # exclude news which are obsolete + models.Q(newsbox_publication_end_date__lte=now) + ) + return query_set + + +class NewsboxModelBase(models.base.ModelBase): + """ + Metaclass used to inject django-newsboxfunctionalities into django + orm. + """ + + def __new__(mcls, class_name, class_bases, class_attrs): + super_new = super(NewsboxModelBase, mcls).__new__ + + # six.with_metaclass() inserts an extra class called 'NewBase' in the + # inheritance tree: Model -> NewBase -> object. But the initialization + # should be executed only once for a given model class. + + # attrs will never be empty for classes declared in the standard way + # (ie. with the `class` keyword). This is quite robust. + if class_name == 'NewBase' and class_attrs == {}: + return super_new(mcls, class_name, class_bases, class_attrs) + + # Also ensure initialization is only performed for subclasses of Model + # (excluding Model class itself). + parents = [b for b in class_bases if isinstance(b, NewsboxModelBase) and + not (b.__name__ == 'NewBase' and b.__mro__ == (b, object))] + if not parents: + return super_new(mcls, class_name, class_bases, class_attrs) + + #retrieve newsbox options in Meta class and delete these from the + #Meta class to avoid django complain about unsupported keys. + #We register our meta options in `_newsbox_meta` + attr_meta = class_attrs.get('Meta', None) + if attr_meta and not getattr(attr_meta, 'ordering', None): + class_attrs['Meta'].ordering = ('-newsbox_date',) + abstract = getattr(attr_meta, 'abstract', False) + newsbox_opts = {} + newsbox_opts_keys = [ + 'detail_url_name', + 'metaclass_base_processor', + 'metaclass_final_processor', + 'trans_fieldnames'] + for opt in newsbox_opts_keys: + newsbox_opt = 'newsbox_' + opt + if hasattr(attr_meta, newsbox_opt): + newsbox_opts[opt] = getattr(attr_meta, newsbox_opt) + delattr(attr_meta, newsbox_opt) + + if 'trans_fieldnames' not in newsbox_opts: + newsbox_opts['trans_fieldnames'] = [] + + # register newsbox_objects manager + class_attrs['newsbox_objects'] = NewsboxManager() + + #Call specific metaclass processor of all bases + if not abstract : + for base in class_bases: + try: + processor = base._newsbox_meta['metaclass_base_processor'] + except (AttributeError, KeyError): + continue + processor = getattr(sys.modules[base.__module__], processor) + processor(mcls, class_name, class_bases, class_attrs, base, newsbox_opts) + + for base in class_bases: + try: + processor = base._newsbox_meta['metaclass_final_processor'] + except (AttributeError, KeyError): + continue + processor = getattr(sys.modules[base.__module__], processor) + processor(mcls, class_name, class_bases, class_attrs, base, newsbox_opts) + + if not 'default_manager' in class_attrs: + class_attrs['default_manager'] = class_attrs['newsbox_objects'] + if not 'objects' in class_attrs: + class_attrs['objects'] = class_attrs['newsbox_objects'] + + # contructs class + cls = super_new(mcls, class_name, class_bases, class_attrs) + + #Add the detail_url_name to _newsbox_meta. if not defined, we build the + #default one with this format : <app_label>_<model_name>_detail + #Names ar lowered. + if not abstract: + detail_url_name = newsbox_opts.get( + 'detail_url_name', + "%s_%s_detail" % (cls._meta.app_label.lower(), + cls._meta.model_name.lower(),) + ) + + newsbox_opts.update( + detail_url_name=detail_url_name, + ) + newsbox_models.append(cls) + cls.add_to_class('_newsbox_meta', newsbox_opts) + return cls + + +@python_2_unicode_compatible +class NewsboxBase(six.with_metaclass(NewsboxModelBase, models.Model)): + """ + Abstract class to build your own news + """ + + # Automatic fields + newsbox_creation_date = models.DateTimeField( + verbose_name=_('creation date'), + auto_now_add=True, + editable=False) + newsbox_changed_date = models.DateTimeField( + verbose_name=_('last update date'), + auto_now=True, + editable=False) + + # Basic Publication Fields + newsbox_date = models.DateTimeField( + verbose_name=_('date'), + default=datetime.now, db_index=True, + ) + + newsbox_publication_start_date = models.DateTimeField( + verbose_name=_('publication start date'), + default=datetime.now, db_index=True, + help_text=_( + 'When the news should go live. ' + 'Status must be "Published" for news to go live.')) + + newsbox_published = models.BooleanField( + verbose_name=_('published'), + blank=True, + default=True,) + + default_manager = NewsboxManager() + objects = default_manager + + def __str__(self): + return six.text_type(self.newsbox_title) + + def has_publish_permission(self, request): + if request.user.is_superuser: + return True + return request.user.has_perm('newsbox.publish_news', self) + + def has_change_permission(self, request): + if request.user.is_superuser: + return True + return request.user.has_perm('newsbox.change_news', self) + + def is_published(self): + if not self.newsbox_published: + return False + + if isinstance(self, NewsboxExpiredBase): + now = datetime.utcnow().replace(tzinfo=utc) + if now < self.newsbox_publication_start_date: + return False + if now > self.newsbox_publication_end_date: + return False + + return True + + def get_slug(self, *args, **kwargs): + return self.newsbox_slug + + def get_absolute_url(self, *args, **kwargs): + return reverse(self._newsbox_meta['detail_url_name'], args=( + self.newsbox_date.strftime("%Y"), + self.newsbox_date.strftime("%m"), + self.newsbox_date.strftime("%d"), + self.get_slug(),)) + + class Meta: + abstract = True + verbose_name = _('news') + verbose_name_plural = _('news') + ordering = ('-newsbox_date',) + newsbox_metaclass_base_processor = 'newsbox_mcls_processor' + +class NewsboxExpiredBase(six.with_metaclass(NewsboxModelBase, models.Model)): + """ + Define News which expires in time and will not be displayed in front + """ + newsbox_publication_end_date = models.DateTimeField( + verbose_name=_('publication end date'), + null=True, blank=True, db_index=True, + help_text=_( + 'When to expire the news.' + 'Leave empty to never expire.')) + + class Meta: + abstract = True + +class NewsboxSEOBase(six.with_metaclass(NewsboxModelBase, models.Model)): + """ + Define News which have SEO fields + """ + + # SEO Fields + newsbox_indexed = models.BooleanField( + verbose_name=_('indexed'), + default=True, + help_text=_( + 'An unindexed news will not be indexed by search engines.')) + + class Meta: + abstract = True + newsbox_metaclass_base_processor = 'newsboxseo_mcls_processor' diff --git a/newsbox/templates/newsbox/detail.html b/newsbox/templates/newsbox/detail.html new file mode 100644 index 0000000000000000000000000000000000000000..09f53f3e859c106a937e4428bca2ea1318781538 --- /dev/null +++ b/newsbox/templates/newsbox/detail.html @@ -0,0 +1,22 @@ +{% load i18n %} + +<article class="newsbox_detail"> + {% block newsbox_detail_header %} + <header> + <h1>{{ news.newsbox_title }}</h1> + <time datetime="{{ news.newsbox_date }}">{{ news.newsbox_date|date:'d M. Y' }}</time> + </header> + {% endblock %} + + + {% block newsbox_detail_item_content %} + <div class="content"> + + {% if news.newsbox_body %} + {{ news.newsbox_body|linebreaks }} + {% else %} + {{ news.newsbox_summary|linebreaks }} + {% endif %} + </div> + {% endblock %} +</article> diff --git a/newsbox/templates/newsbox/list.html b/newsbox/templates/newsbox/list.html new file mode 100644 index 0000000000000000000000000000000000000000..e3d263e90600b8f141e4d49a35e311e7e8060330 --- /dev/null +++ b/newsbox/templates/newsbox/list.html @@ -0,0 +1,74 @@ +{% if news|length > 0 %} + {% load i18n %} + <section class="newsbox_plugin"> + + {% block newsbox_list_header %} + {% if title %} + <h1> + {% if title_url %} + <a href="{{ title_url }}">{{ title }}</a> + {% else %} + {{ title }} + {% endif %} + </h1> + {% endif %} + {% endblock %} + + + {% block newsbox_list %} + <div class="list"> + + {% for news in newsset %} + {% block newsbox_list_item %} + <div class="news"> + <header> + {% block newsbox_list_item_header %} + {% with news.get_absolute_url as url %} + <h2><a href="{{ url }}">{{ news.newsbox_title }}</a></h2> + {% endwith %} + <time datetime="{{ news.newsbox_date }}">{{ news.newsbox_date|date:'d M. Y' }}</time> + {% endblock %} + </header> + + {% block newsbox_list_item_content %} + <div class="summary"> + {{ news.newsbox_summary|linebreaks }} + {% if news.newsbox_body %} + <p class="readmore"><a href="{{ news.get_absolute_url }}"> + {% trans "Read more" %} + </a></p> + {% endif %} + </div> + {% endblock %} + + </div> + {% endblock %} + {% endfor %} + + + {% block newsbox_pager %} + {% if with_pager %} + <div class="pager"> + {% if newsset.has_previous %} + <a class="prev" href="?page={{ newsset.previous_page_number }}">{% trans "Previous news" %}</a> + {% endif %} + + <span class="current"> + {% blocktrans with newsset.number as number and newsset.paginator.num_pages as total %}Page {{ number }} on {{ total }}{% endblocktrans %} + </span> + + {% if newsset.has_next %} + <a class="next" href="?page={{ newsset.next_page_number }}">{% trans "Next news" %}</a> + {% endif %} + </div> + {% elif all_news_url %} + <a class="readmore" href="{{ all_news_url }}">{% trans "See all news" %}</a></p> + {% endif %} + {% endblock %} + + </div> + {% endblock %} + </section> +{% else %} + {% block newsbox_no_news %}{% endblock %} +{% endif %} diff --git a/newsbox/templatetags/__init__.py b/newsbox/templatetags/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/newsbox/templatetags/get_placeholder_content.py b/newsbox/templatetags/get_placeholder_content.py new file mode 100644 index 0000000000000000000000000000000000000000..f649636b8e95008f28bf634d5900b6ac9f681498 --- /dev/null +++ b/newsbox/templatetags/get_placeholder_content.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django import template +from django.utils.safestring import mark_safe +from classytags.arguments import Argument +from classytags.core import Options +from cms.templatetags.cms_tags import RenderPlaceholder + + +register = template.Library() + + +class GetPlaceholderContent(RenderPlaceholder): + """ + With this tag, you can retrieve a placeholder's content into a variable + + Exemple : + {% get_placeholder_content news.newsbox_body as body %} + {% if body %} + {{ body|safe }} + some extra html + {% else %} + fall back + {% endif %} + {% endget_placeholder_content %} + """ + name = 'get_placeholder_content' + options = Options( + Argument('placeholder', resolve=True), + Argument('width', default=None, required=False), + 'language', + Argument('language', default=None, required=False), + 'as', + Argument('varname', resolve=False), + blocks=[ + ('endget_placeholder_content', 'nodelist'), + ] + ) + + def render_tag(self, context, placeholder, width, varname, language=None, nodelist=None): + placeholder_output = None + if placeholder: + placeholder_output = super(GetPlaceholderContent, self).render_tag( + context, placeholder, width, language) + + context.push() + context[varname] = mark_safe(placeholder_output) + output = nodelist.render(context) + context.pop() + return output + + +register.tag(GetPlaceholderContent) diff --git a/newsbox/urls.py b/newsbox/urls.py new file mode 100644 index 0000000000000000000000000000000000000000..b0164b0782d04a997421c299a72bf190996faaa8 --- /dev/null +++ b/newsbox/urls.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.utils.text import slugify +from django.conf.urls import patterns, url, include +from django.conf.urls.i18n import i18n_patterns + +from .models import newsbox_models +from .views import NewsboxArchiveView, NewsboxYearArchiveView, \ + NewsboxMonthArchiveView, NewsboxDayArchiveView, NewsboxDetailView + +def get_urls( + archive_view=NewsboxArchiveView, + year_archive_view=NewsboxYearArchiveView, + month_archive_view=NewsboxMonthArchiveView, + day_archive_view=NewsboxDayArchiveView, + detail_view=NewsboxDetailView): + + urls = ['',] + for model in newsbox_models : + app_name = model._meta.app_label.lower() + model_name = model.__name__.lower() + + viewurl = 'newsbox/%s/%s/'\ + % (app_name, model_name,) + urls.append( + url( + r'^%s$' % viewurl, + archive_view.as_view( + model=model,), + name='%s_%s_list' % (app_name, model_name), + ), + ) + viewurl=viewurl+'(?P<year>\d{4})/' + urls.append( + url( + r'^%s$' % viewurl, + year_archive_view.as_view( + model=model,), + name='%s_%s_list_y' % (app_name, model_name), + ), + ) + viewurl=viewurl+'(?P<month>\d{2})/' + urls.append( + url( + r'^%s$' % viewurl, + month_archive_view.as_view( + model=model,), + name='%s_%s_list_ym' % (app_name, model_name), + ), + ) + viewurl=viewurl+'(?P<day>\d{2})/' + urls.append( + url( + r'^%s$' % viewurl, + day_archive_view.as_view( + model=model,), + name='%s_%s_list_ymd' % (app_name, model_name), + ), + ) + urls.append( + url( + r'^%s(?P<slug>[0-9a-zA-Z_-]+)/$' % viewurl, + detail_view.as_view( + model=model,), + name='%s_%s_detail' % (app_name, model_name), + ), + ) + return urls + +urls = get_urls() +urlpatterns = patterns(*urls) diff --git a/newsbox/utils.py b/newsbox/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..c53eac001478a2e4176cf35ade0b204ebd7ed5ca --- /dev/null +++ b/newsbox/utils.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + +def get_newsmodels_list(): + from django.db.models import get_app, get_models + pass diff --git a/newsbox/views.py b/newsbox/views.py new file mode 100644 index 0000000000000000000000000000000000000000..f47c0baed77066c8e2fddb765b4439780125f554 --- /dev/null +++ b/newsbox/views.py @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.http import Http404, HttpResponse +from django.shortcuts import render_to_response, get_object_or_404 +from django.template.context import RequestContext +from django.utils.translation import ugettext as _ +from django.db.models.loading import get_model +from django.views.generic.dates import DateDetailView, ArchiveIndexView, \ + YearArchiveView, MonthArchiveView, DayArchiveView + +from .models import NewsboxBase + +class NewsboxBaseArchiveView(object): + """ + This view is responsible for displaying a list of newsbox + """ + date_field = "newsbox_date" + slug_field = "newsbox_slug" + paginate_by = 10 + make_object_list = True + allow_future = True + template_name = "newsbox/list.html" + context_object_name = 'newsset' + title = None + + def update_context_data(self, context, **kwargs): + with_pager = context['is_paginated'] + context['newsset'].number = context['page_obj'].number + context['newsset'].has_previous = context['page_obj'].has_previous + context['newsset'].has_next = context['page_obj'].has_next + context['newsset'].next_page_number = context['page_obj'].next_page_number + context['newsset'].previous_page_number = context['page_obj'].previous_page_number + context['newsset'].paginator = context['paginator'] + if self.title == None: + title = self.model._meta.verbose_name_plural.capitalize() + else: + title=self.title + context.update({ + 'instance': None, + 'title': title, + 'title_url': '', + 'newsbox_opts':self.model._newsbox_meta, + 'with_pager': with_pager, + }) + return context + + def get_queryset(self): + if self.request.user.is_staff: + return self.model.objects.all() + else: + return self.model.objects.published() + +class NewsboxArchiveView(NewsboxBaseArchiveView, ArchiveIndexView): + def get_context_data(self, **kwargs): + context = super(NewsboxArchiveView, self).get_context_data(**kwargs) + NewsboxBaseArchiveView.update_context_data(self, context, **kwargs) + return context + +class NewsboxYearArchiveView(NewsboxBaseArchiveView, YearArchiveView): + def get_context_data(self, **kwargs): + context = super(NewsboxYearArchiveView, self).get_context_data(**kwargs) + NewsboxBaseArchiveView.update_context_data(self, context, **kwargs) + return context + + def get_queryset(self): + if self.request.user.is_staff: + return self.model.objects.all() + else: + return self.model.objects.published() + +class NewsboxMonthArchiveView(NewsboxBaseArchiveView, MonthArchiveView): + month_format = "%m" + def get_context_data(self, **kwargs): + context = super(NewsboxMonthArchiveView, self).get_context_data(**kwargs) + NewsboxBaseArchiveView.update_context_data(self, context, **kwargs) + return context + +class NewsboxDayArchiveView(NewsboxBaseArchiveView, DayArchiveView): + month_format = "%m" + def get_context_data(self, **kwargs): + context = super(NewsboxDayArchiveView, self).get_context_data(**kwargs) + NewsboxBaseArchiveView.update_context_data(self, context, **kwargs) + return context + + + +class NewsboxDetailView(DateDetailView): + """ + This view is responsible for displaying a newsbox + """ + month_format = "%m" + date_field = "newsbox_date" + slug_field = "newsbox_slug" + template_name = "newsbox/detail.html" + context_object_name = "news" + allow_future = True + + def get_context_data(self, **kwargs): + context = super(NewsboxDetailView, self).get_context_data(**kwargs) + if 'NewsboxCMSBase' in (base.__name__ for base in self.model.__bases__): + from menus.utils import set_language_changer + set_language_changer(self.request, self.object.get_absolute_url) + return context + + def get_object(self): + # We check user permission + obj = super(NewsboxDetailView, self).get_object() + if( + not obj.is_published() + and not obj.has_change_permission(self.request) + ): + raise Http404 + return obj diff --git a/newsbox_cms/__init__.py b/newsbox_cms/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/newsbox_cms/admin.py b/newsbox_cms/admin.py new file mode 100644 index 0000000000000000000000000000000000000000..14388ef7e5fb5aad27006684fa903576fe2284c3 --- /dev/null +++ b/newsbox_cms/admin.py @@ -0,0 +1,139 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.contrib import admin +from django.core.urlresolvers import reverse +from django.utils import formats +from django.utils.translation import ugettext_lazy as _ +from django.utils import six + +try: + from cms.admin.placeholderadmin import FrontendEditableAdminMixin, PlaceholderAdminMixin +except ImportError: + # temporary django-cms backward compat + from cms.admin.placeholderadmin import ( + FrontendEditableAdmin as FrontendEditableAdminMixin, + PlaceholderAdmin as PlaceholderAdminMixin + ) + +from newsbox.admin import NewsboxBaseAdmin, remove_field_from_fieldsets, add_fields_to_fieldset + + +class CustomModelCMSAdmin(admin.ModelAdmin): + class Media: + css = { + "all": ("newsbox_cms/custom_model.css",) + } + + +def CustomModelCMSAdminFactory( + object_title=None, + edit_link_short_description=_('title'), + edit_link_admin_order_field=None, +): + class klass(CustomModelCMSAdmin): + + def edit_link_title(self, obj, func_or_attr=None): + if func_or_attr is not None: + if isinstance(func_or_attr, basestring): + if not hasattr(obj, func_or_attr): + raise ValueError( + 'func_or_attr is a string, it needs to be' + ' an object attribute (eventualy a function)' + ) + + attr = getattr(obj, func_or_attr) + if callable(attr): + title = attr(obj) + else: + title = attr + + elif callable(func_or_attr): + title = func_or_attr(obj) + else: + raise ValueError('func_or_attr needs to be either a string or a collable') + + else: + title = six.text_type(obj) + return title + + def edit_link(self, obj): + """ + build the change list edit link + """ + output = '' + edit_url = reverse( + 'admin:%s_%s_change' % (obj._meta.app_label, obj._meta.module_name), + args=[obj.pk]) + + show_url = None + if hasattr(obj, 'get_absolute_url'): + show_url = obj.get_absolute_url() + + output = '<a class="edit" href="{edit_url}" title="{edit_label}"></a>' + + if show_url: + output += '<a class="title" href="{show_url}" target="_parent" title="{show_label}">{title}</a>' + else: + output += '<span class="title">{title}</span>' + + return output.format( + edit_url=edit_url, show_url=show_url, show_label=_("show object's page"), + title=self.edit_link_title(obj, object_title), edit_label=_("edit object's parameters")) + + edit_link.allow_tags = True + edit_link.short_description = edit_link_short_description + edit_link.admin_order_field = edit_link_admin_order_field + + + def get_list_display(self, request): + list_display = super(CustomModelCMSAdmin, self).get_list_display(request) + list_display = list(list_display) + del list_display[0] + list_display.insert(0, 'edit_link') + return list_display + + def get_list_display_links(self, request, list_display): + return [] + + return klass + + +def newsbox_admin_title(obj): + return '{date}<br/>{title}'.format( + date=formats.date_format(obj.newsbox_date, 'DATE_FORMAT'), + title=six.text_type(obj) + ) + + +class NewsboxCMSAdmin( + #XXX: hvad TranslatableAdmin doesn't support admin_order_field on translated field + # CustomModelCMSAdminFactory(edit_link_admin_order_field='newsbox_title'), + CustomModelCMSAdminFactory(object_title=newsbox_admin_title, edit_link_admin_order_field='newsbox_date'), + FrontendEditableAdminMixin, + PlaceholderAdminMixin, + NewsboxBaseAdmin +): + + def __init__(self, *args, **kwargs): + # We manage the edit link ourself + self.list_display_links = (None, ) + return super(NewsboxCMSAdmin, self).__init__(*args, **kwargs) + + def get_fieldsets(self, request, obj=None): + fieldsets = super(NewsboxCMSAdmin, self).get_fieldsets(request, obj) + remove_field_from_fieldsets('newsbox_body', fieldsets) + add_fields_to_fieldset( + ['newsbox_summary'], + fieldsets, + same_fieldset_as='newsbox_published', + replace_existing_field=True, + remove_empty_fieldset=True, + ) + return fieldsets + + def get_list_display(self, request): + list_display = super(NewsboxCMSAdmin, self).get_list_display(request) + list_display.remove('newsbox_date') + list_display.remove('get_newsbox_slug') + return list_display diff --git a/newsbox_cms/cms_plugins.py b/newsbox_cms/cms_plugins.py new file mode 100644 index 0000000000000000000000000000000000000000..d42181a9ad6da99d06c76cc52e022ed9d7aee951 --- /dev/null +++ b/newsbox_cms/cms_plugins.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.utils.translation import ugettext as _ +from django.db import models +from django.contrib import admin +from cms.plugin_base import CMSPluginBase +from newsbox.models import NewsboxBase + +class NewsboxPluginBase(CMSPluginBase): + name = _("News list") # Name of the plugin + render_template = "newsbox_cms/list-cms.html" # template to render the plugin + raw_id_fields = ('page_link',) + + def render(self, context, instance, placeholder): + from django.db.models.loading import get_model + + NewsboxModel = instance.newsbox_model + + if not NewsboxModel or not issubclass(NewsboxModel, NewsboxBase): + raise Exception(_("The choosen news type to display is invalid")) + + if instance.numitems > 0 : + with_pager = instance.with_pager + + if with_pager : + from django.core.paginator import Paginator, \ + EmptyPage, PageNotAnInteger + + paginator = Paginator(NewsboxModel.objects.published(), + instance.numitems) + page = context['request'].GET.get('page') + try: + newsset = paginator.page(page) + except PageNotAnInteger: + # If page is not an integer, deliver first page. + newsset = paginator.page(1) + except EmptyPage: + # If page is out of range (e.g. 9999), deliver last page of results. + newsset = paginator.page(paginator.num_pages) + else : + newsset = NewsboxModel.objects.published()[:instance.numitems] + else : + newsset = NewsboxModel.objects.published() + with_pager = False + context.update({ + 'instance': instance, + 'title': instance.title, + 'newsset':newsset, + 'newsbox_opts':NewsboxModel._newsbox_meta, + 'with_pager':with_pager, + }) + + if instance.page_link: + context.update({ + 'title_url' : instance.page_link.get_absolute_url(), + 'all_news_url': instance.page_link.get_absolute_url(), + }) + return context + + class Meta: + abstract = True diff --git a/newsbox_cms/locale/fr/LC_MESSAGES/django.mo b/newsbox_cms/locale/fr/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..27fc1c4239e93e2dacb771170c4c9f4feb1dca80 Binary files /dev/null and b/newsbox_cms/locale/fr/LC_MESSAGES/django.mo differ diff --git a/newsbox_cms/locale/fr/LC_MESSAGES/django.po b/newsbox_cms/locale/fr/LC_MESSAGES/django.po new file mode 100644 index 0000000000000000000000000000000000000000..39af73d52916739fd09a6aeaa7427bfb465a91e8 --- /dev/null +++ b/newsbox_cms/locale/fr/LC_MESSAGES/django.po @@ -0,0 +1,84 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-02-20 10:29+0100\n" +"PO-Revision-Date: 2014-02-20 10:31+0100\n" +"Last-Translator: \n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: admin.py:20 +msgid "title" +msgstr "Titre" + +#: admin.py:70 +msgid "show object's page" +msgstr "Afficher la page de l'objet" + +#: admin.py:71 +msgid "edit object's parameters" +msgstr "Éditer les paramètres de l'objet" + +#: cms_plugins.py:10 +msgid "News list" +msgstr "Liste d'actualités" + +#: cms_plugins.py:19 +msgid "The choosen news type to display is invalid" +msgstr "Le type d'actualité à afficher choisi est invalide" + +#: models.py:12 +msgid "Title" +msgstr "Titre" + +#: models.py:14 +msgid "Title to display before the list" +msgstr "Titre à afficher avant la liste" + +#: models.py:16 +msgid "Number of news" +msgstr "Nombre d'actualités" + +#: models.py:18 +msgid "Number of news to display. \"0\" allow you to display ALL news" +msgstr "numbre d'actualités à afficher. Saisir \"0\" permet de TOUTES les afficher" + +#: models.py:21 +msgid "Display a pager" +msgstr "Affiche une pagination" + +#: models.py:24 +msgid "All news page" +msgstr "Toutes les pages des actualités" + +#: models.py:26 +msgid "Page displaying all news" +msgstr "Affichage de toutes les actualités" + +#: models.py:31 +#, python-format +msgid "Display of a news" +msgid_plural "Display of %(nb)d news" +msgstr[0] "Affichage de l'actualité" +msgstr[1] "Affichage de %(nb)d actualités" + +#: models.py:35 +msgid "Display of all news" +msgstr "Affichage de toutes les actualités" + +#: templates/newsbox_cms/list-cms.html:11 +msgid "Read more" +msgstr "Lire la suite" + +#~ msgid "News type to display" +#~ msgstr "Type d'actualité à afficher" diff --git a/newsbox_cms/models.py b/newsbox_cms/models.py new file mode 100644 index 0000000000000000000000000000000000000000..3a28d46c21a96dcf680f923e268e8176af6e1dc2 --- /dev/null +++ b/newsbox_cms/models.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.utils.translation import ugettext_lazy as _, ungettext_lazy +from django.utils import six +from django.utils.encoding import python_2_unicode_compatible +from django.db import models +from cms.models.pluginmodel import CMSPlugin +from cms.models.fields import PageField, PlaceholderField +from djangocms_text_ckeditor.fields import HTMLField + +from newsbox.models import NewsboxModelBase + + +def newsboxcms_mcls_processor(mcls, class_name, class_bases, class_attrs, base, newsbox_opts): + class_attrs['newsbox_summary'] = HTMLField( + verbose_name=_('summary')) + class_attrs['newsbox_body'] = PlaceholderField( + 'newsbox_body', + verbose_name=_('body')) + + if 'newsbox_body' in newsbox_opts['trans_fieldnames']: + newsbox_opts['trans_fieldnames'].remove('newsbox_body') + + +@python_2_unicode_compatible +class NewsboxPluginBase(CMSPlugin): + title = models.CharField( + verbose_name=_('Title'), + max_length=255, blank=True, null=True, + help_text=_('Title to display before the list')) + numitems = models.PositiveSmallIntegerField( + verbose_name=_('Number of news'), + default=2, + help_text=_('Number of news to display. ' + '"0" allow you to display ALL news')) + with_pager = models.BooleanField( + verbose_name=_('Display a pager'), + default=False) + + page_link = PageField(verbose_name=_('All news page'), + null=True, blank=True, + help_text=_('Page displaying all news')) + + def __str__(self): + if self.numitems > 0: + return six.text_type(ungettext_lazy( + 'Display of a news', + 'Display of %(nb)d news', + self.numitems + ) % {'nb':self.numitems}) + return six.text_type(_('Display of all news')) + + class Meta: + abstract = True + + +class NewsboxCMSBase(six.with_metaclass(NewsboxModelBase, models.Model)): + + class Meta: + abstract = True + newsbox_metaclass_base_processor = 'newsboxcms_mcls_processor' diff --git a/newsbox_cms/static/newsbox_cms/custom_model.css b/newsbox_cms/static/newsbox_cms/custom_model.css new file mode 100644 index 0000000000000000000000000000000000000000..32b677ef3d8b19713d39dc6acdfa3505bf91cf08 --- /dev/null +++ b/newsbox_cms/static/newsbox_cms/custom_model.css @@ -0,0 +1,11 @@ + +body.change-list #result_list td a.edit { + float:right; + background:url("../cms/img/pagetree/sprite.png") no-repeat scroll 0px 0px transparent; + width:18px; + height:18px; + display:inline-block; + background-position: -40px -20px; + margin-top: 0px; + vertical-align: middle; +} diff --git a/newsbox_cms/templates/newsbox_cms/detail-cms.html b/newsbox_cms/templates/newsbox_cms/detail-cms.html new file mode 100644 index 0000000000000000000000000000000000000000..9b4bdc61b3e97ab53bca1c84a28da8c81b852fae --- /dev/null +++ b/newsbox_cms/templates/newsbox_cms/detail-cms.html @@ -0,0 +1,22 @@ +{% extends "newsbox/detail.html" %} +{% load i18n %} +{% load get_placeholder_content cms_tags %} + +{% block newsbox_detail_header %} + <header> + <h1>{% render_model news "newsbox_title" %}</h1> + <time datetime="{{ news.newsbox_date }}">{{ news.newsbox_date|date:'d M. Y' }}</time> + </header> +{% endblock %} + +{% block newsbox_detail_item_content %} + <div class="content"> + {% render_placeholder news.newsbox_body %} + + {% get_placeholder_content news.newsbox_body as body %} + {% if not body %} + {{ news.newsbox_summary|safe }} + {% endif %} + {% endget_placeholder_content %} + </div> +{% endblock %} diff --git a/newsbox_cms/templates/newsbox_cms/list-cms.html b/newsbox_cms/templates/newsbox_cms/list-cms.html new file mode 100644 index 0000000000000000000000000000000000000000..812f8b8a9b689308a4c68cb411e6ac1351ad0f5d --- /dev/null +++ b/newsbox_cms/templates/newsbox_cms/list-cms.html @@ -0,0 +1,18 @@ +{% extends "newsbox/list.html" %} +{% load i18n %} +{% load get_placeholder_content %} + +{% block newsbox_list_item_content %} + + <div class="summary"> + {{ news.newsbox_summary|safe }} + {% get_placeholder_content news.newsbox_body as body %} + + {% if body %} + <p class="readmore"><a href="{{ news.get_absolute_url }}"> + {% trans "Read more" %} + </a></p> + {% endif %} + {% endget_placeholder_content %} + </div> +{% endblock %} diff --git a/newsbox_hvad/__init__.py b/newsbox_hvad/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/newsbox_hvad/admin.py b/newsbox_hvad/admin.py new file mode 100644 index 0000000000000000000000000000000000000000..fb474b0a2f64e01bfa080c3756085bbd02735d9b --- /dev/null +++ b/newsbox_hvad/admin.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +import copy + +from django.conf import settings +from hvad.admin import TranslatableAdmin +from hvad.forms import translatable_modelform_factory +from django.utils.translation import ugettext_lazy as _ +from django.contrib.admin.util import flatten_fieldsets +from django.utils.functional import curry + + +def edit_translation_links(obj): + output = '' + for lang in obj.get_available_languages(): + output += ( + '<a href="./%s/?language=%s" ' + 'target="_parent" title="Edit this %s in %s">%s' + '</a>' + ) % (obj.pk, lang, obj._meta.verbose_name, lang.upper(), lang.upper(),) + return output +edit_translation_links.allow_tags = True +edit_translation_links.short_description = _('translations') + + + +class NewsboxHVADBaseAdmin(TranslatableAdmin): + + #XXX: hvad TranslatableAdmin doesn't support search_fields + # search_fields = ['newsbox_title', 'newsbox_summary', ] + # date_hierarchy = 'newsbox_publication_start_date' + + def get_list_display(self, request): + list_display = super(NewsboxHVADBaseAdmin, self).get_list_display(request) + # prevent modifying class list_display variable + list_display = copy.deepcopy(list_display) + if settings.LANGUAGES and len(settings.LANGUAGES) > 1: + list_display.insert(1, edit_translation_links) + + return list_display + + def get_form(self, request, obj=None, **kwargs): + """ + This function is a workaround to an hvad issue. It doesn't use + get_fieldsets function. + + Returns a Form class for use in the admin add view. This is used by + add_view and change_view. + """ + fieldsets = self.get_fieldsets(request, obj) + if fieldsets: + fields = flatten_fieldsets(fieldsets) + else: + fields = None + if self.exclude is None: + exclude = [] + else: + exclude = list(self.exclude) + exclude.extend(kwargs.get("exclude", [])) + exclude.extend(self.get_readonly_fields(request, obj)) + # Exclude language_code, adding it again to the instance is done by + # the LanguageAwareCleanMixin (see translatable_modelform_factory) + exclude.append('language_code') + old_formfield_callback = curry(self.formfield_for_dbfield, + request=request) + defaults = { + "form": self.form, + "fields": fields, + "exclude": exclude, + "formfield_callback": old_formfield_callback, + } + defaults.update(kwargs) + language = self._language(request) + return translatable_modelform_factory(language, self.model, **defaults) + + +class NewsboxHVADAdmin(NewsboxHVADBaseAdmin): + pass diff --git a/newsbox_hvad/models.py b/newsbox_hvad/models.py new file mode 100644 index 0000000000000000000000000000000000000000..18960f0fc008abdef97410fb62ae73a681e29757 --- /dev/null +++ b/newsbox_hvad/models.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +import sys + +from django.db import models +from django.core.urlresolvers import reverse +from django.utils.translation import ugettext_lazy as _, get_language, activate +from django.utils import six +from django.utils.encoding import python_2_unicode_compatible +from hvad.manager import TranslationManager +from hvad.models import TranslatableModel, TranslatedFields, \ + TranslatableModelBase +from newsbox.models import NewsboxModelBase, NewsboxManager, \ + NewsboxBase, newsbox_models + + +class NewsboxHVADManager(TranslationManager, NewsboxManager): + pass + +def newsboxhvad_mcls_processor(mcls, class_name, class_bases, class_attrs, base, newsbox_opts): + translatedFields={} + for trans_field in newsbox_opts['trans_fieldnames']: + translatedFields[trans_field] = class_attrs.pop(trans_field) + class_attrs['translations'] = TranslatedFields(**translatedFields) + class_attrs['newsbox_objects'] = NewsboxHVADManager() + #class_attrs['default_manager'] = class_attrs['newsbox_objects'] + + +class NewsboxHVADModelBase(NewsboxModelBase, TranslatableModelBase): + pass + + +@python_2_unicode_compatible +class NewsboxHVADBase(six.with_metaclass(NewsboxHVADModelBase, TranslatableModel)): + """ + Define News which expires in time and will not be displayed in front + """ + + default_manager = NewsboxHVADManager() + objects = default_manager + + def __str__(self): + return self.lazy_translation_getter( + 'newsbox_title', + _('News n° %s') % self.pk) + + def get_slug(self, language=None, *args, **kwargs): + """ + Returns the slug for this object for the given language. + """ + if language is None or language == self.language_code: + return self.safe_translation_getter('newsbox_slug') + else: + instance = self.__class__.objects.language(language).get(pk=self.pk) + return instance.safe_translation_getter('newsbox_slug') + + def get_absolute_url(self, language=None, *args, **kwargs): + """ + Build url for the given language. + """ + current_language = get_language() + + if not language: + language = current_language + + if language in self.get_available_languages(): + activate(language) + url = reverse(self._newsbox_meta['detail_url_name'], args=( + self.newsbox_date.strftime("%Y"), + self.newsbox_date.strftime("%m"), + self.newsbox_date.strftime("%d"), + self.get_slug(language=language),)) + activate(current_language) + return url + + return "./" + + + class Meta: + abstract = True + verbose_name = _('news') + verbose_name_plural = _('news') + #newsbox_metaclass_base_processor = 'newsboxhvad_mcls_processor' + newsbox_metaclass_final_processor = 'newsboxhvad_mcls_processor' diff --git a/newsbox_hvad/urls.py b/newsbox_hvad/urls.py new file mode 100644 index 0000000000000000000000000000000000000000..ca160a4bf2d536932ce4cdd34c9502253badc15c --- /dev/null +++ b/newsbox_hvad/urls.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.conf.urls import patterns +from newsbox.urls import get_urls + +from .views import NewsboxHVADDetailView + +urls = get_urls(detail_view=NewsboxHVADDetailView) +urlpatterns = patterns(*urls) diff --git a/newsbox_hvad/views.py b/newsbox_hvad/views.py new file mode 100644 index 0000000000000000000000000000000000000000..209f38ab3c90f7a0ca4959cdc77d392457d980e3 --- /dev/null +++ b/newsbox_hvad/views.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from newsbox.views import NewsboxDetailView + +class NewsboxHVADDetailView(NewsboxDetailView): + + def get_queryset(self): + """ + As slug_field is translated, we need to use translation aware + queryset. + """ + return self.model.objects.using_translations() diff --git a/setup.py b/setup.py new file mode 100755 index 0000000000000000000000000000000000000000..9c201cfda104f9206a629e8a453c445a05eabb89 --- /dev/null +++ b/setup.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from setuptools import setup, find_packages +import os +import newsbox + + +CLASSIFIERS = [ + 'Development Status :: 5 - Production/Stable', + 'Environment :: Web Environment', + 'Framework :: Django', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: BSD License', + 'Operating System :: OS Independent', + 'Programming Language :: Python', + 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', + 'Topic :: Software Development', + 'Topic :: Software Development :: Libraries :: Application Frameworks', + "Programming Language :: Python :: 2.6", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3.3", +] + +setup( + author="Dylann Cordel", + author_email="d.cordel@webu.coop", + name='django-newsbox', + version=newsbox.__version__, + description='A Django and Django CMS APP providing news support', + long_description=open(os.path.join(os.path.dirname(__file__), 'README.md')).read(), + url='https://dev.webu.coop/webu/django-newsbox', + license='BSD License', + platforms=['OS Independent'], + classifiers=CLASSIFIERS, + install_requires=[ + 'Django>=1.6,<1.7', + ], + packages=find_packages(exclude=["project", "project.*"]), + include_package_data=True, + zip_safe=False, +) diff --git a/test_requirements/django-1.6.txt b/test_requirements/django-1.6.txt new file mode 100644 index 0000000000000000000000000000000000000000..9cec9f618eda058f22b41cbaf04b5620fce6cd9d --- /dev/null +++ b/test_requirements/django-1.6.txt @@ -0,0 +1,3 @@ +-r requirements_base.txt +django>=1.6,<1.7 +https://github.com/KristianOellegaard/django-hvad/archive/master.zip#egg=hvad diff --git a/test_requirements/django-1.6_cms-3.0.txt b/test_requirements/django-1.6_cms-3.0.txt new file mode 100644 index 0000000000000000000000000000000000000000..2b2c0972a9b20f03e411a05d14236fed9c2069c3 --- /dev/null +++ b/test_requirements/django-1.6_cms-3.0.txt @@ -0,0 +1,37 @@ +# Currently, 3.0 is not yet released, so we use the develop branch +git+https://github.com/divio/django-cms.git@develop#egg=django-cms + +# This is django-cms test requirements + +django>=1.6,<1.7 +django-reversion>=1.8 + +coverage==3.7 +python-coveralls==2.4.0 +docopt==0.6.1 +unittest-xml-reporting==1.0.3 +sphinx +Pillow==2.0 +django-classy-tags>=0.5 +South>=0.7.2 +html5lib>=0.90 +django-mptt>=0.6 +django-sekizai>=0.7 +argparse +dj-database-url +selenium +django-debug-toolbar +https://github.com/KristianOellegaard/django-hvad/archive/master.zip#egg=hvad +-e git+git://github.com/divio/djangocms-admin-style.git#egg=djangocms-admin-style +-e git+git://github.com/divio/djangocms-text-ckeditor.git#egg=djangocms-text-ckeditor +-e git+git://github.com/divio/djangocms-column.git#egg=djangocms-column +-e git+git://github.com/divio/djangocms-style.git#egg=djangocms-style +-e git+git://github.com/divio/djangocms-file.git#egg=djangocms-file +-e git+git://github.com/divio/djangocms-flash.git#egg=djangocms-flash +-e git+git://github.com/divio/djangocms-googlemap.git#egg=djangocms-googlemap +-e git+git://github.com/divio/djangocms-inherit.git#egg=djangocms-inherit +-e git+git://github.com/divio/djangocms-picture.git#egg=djangocms-picture +-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 +pyflakes diff --git a/test_requirements/requirements_base.txt b/test_requirements/requirements_base.txt new file mode 100644 index 0000000000000000000000000000000000000000..66f9b96ea8e6d0c687f99422c8cf031bf35578c3 --- /dev/null +++ b/test_requirements/requirements_base.txt @@ -0,0 +1,3 @@ +south>=0.7.2 +pytz +beautifulsoup4 diff --git a/tests/myapp/README.md b/tests/myapp/README.md new file mode 100644 index 0000000000000000000000000000000000000000..635d7799195e509b623cb97c955cd499464b8bca --- /dev/null +++ b/tests/myapp/README.md @@ -0,0 +1,90 @@ +initial fixtures +================ + +## News + +If not precised, news have those default values : + +* newsbox_slug : news-%(pk)d +* newsbox_title : News %(pk)d +* newsbox_date : 2014-02-22 10:00:00 +* newsbox_publication_start_date : 1985-07-02 10:00:00 +* newsbox_published : True +* newsbox_summary : Summary of the news %(pk)d +* newsbox_body : Body of the news %(pk)d + +### List of all available test News + +1. A basic classic published news +2. A not published news via newsbox_published + * newsbox_published = False +3. A not published news via newsbox_publication_start_date + * newsbox_publication_start_date = 2020-01-01 10:00:00 +4. A published news without body + * newsbox_body = '' +5. A not published news via newsbox_published (same as #2) + * newsbox_published = False +6. A published news about an old event + * newsbox_date = 2005-07-15 10:00:00 +7. A published news about a future event + * newsbox_date = 2020-01-01 10:00:00 + +## NewsExpired + +If not precised, Expired news have default values from news for classic news +fields and those values for specific Expired news fields : + +* newsbox_publication_end_date : 2014-02-22 10:00:00 + +### List of all available test NewsExpired + +* from 1 to 4 : same as News +5. A not published news via his expiration's date + * newsbox_publication_end_date = 2000-01-01 10:00:00 +* from 6 to 7 : same as News + +## NewsSEO + +If not precised, SEO news have default values from news for classic news fields +and those values for specific SEO news fields : + +* newsbox_indexed : True +* newsbox_meta_description : Meta description of the news %(pk)d +* newsbox_meta_keywords : keyword1, keyword2, news-%(pk)d + +### List of all available test NewsExpired + +* from 1 to 5 : same as News +6. same as #6 of News but not indexed news via newsbox_indexed + * newsbox_indexed = False +7. same as #7 of News + +## NewsComplete + +If not precised, Complete news have default values from news for classic news +fields, from NewsSEO for seo fields, from NewsExpired for expired fields. + +### List of all available test NewsComplete + +* from 1 to 5 : same as NewsExpired +6. Same as #6 of NewsSEO +7. same as #7 of News + +## NewsExtended + +If not precised, Complete news have default values from news for classic news +fields, from NewsSEO for seo fields, from NewsExpired for expired fields and +those values for specific NewsExtended news fields : + +* general_field : Test +* content_field : Extra content of the news %(pk)d +* seo_field : Extra SEO of the news %(pk)d + +### List of all available test NewsExtended + +* from 1 to 7 : same as NewsComplete + +## Code used to generate test news + +You can see the code used to generate initial fixtures in utils.py in this +directory. diff --git a/tests/myapp/__init__.py b/tests/myapp/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..40a96afc6ff09d58a702b76e3f7dd412fe975e26 --- /dev/null +++ b/tests/myapp/__init__.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*- diff --git a/tests/myapp/admin.py b/tests/myapp/admin.py new file mode 100644 index 0000000000000000000000000000000000000000..10fbc62d88a4dbf713c5dca5c2a52cc343f4480c --- /dev/null +++ b/tests/myapp/admin.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from django.contrib import admin +from newsbox.admin import NewsboxAdmin, NewsboxSEOAdmin, NewsboxExpiredAdmin + +from .models import News, NewsSEO, NewsExpired, NewsComplete, NewsExtended + +class NewsAdmin(NewsboxAdmin): + pass + +admin.site.register(News, NewsAdmin) + + +class NewsSEOAdmin(NewsboxSEOAdmin): + pass + +admin.site.register(NewsSEO, NewsSEOAdmin) + + +class NewsExpiredAdmin(NewsboxExpiredAdmin): + pass + +admin.site.register(NewsExpired, NewsExpiredAdmin) + + +class NewsCompleteAdmin(NewsboxSEOAdmin, NewsboxExpiredAdmin): + pass + +admin.site.register(NewsComplete, NewsCompleteAdmin) + + +class NewsExtendedAdmin(NewsboxSEOAdmin, NewsboxExpiredAdmin): + def get_fieldsets(self, request, obj=None): + fieldsets = super(NewsExtendedAdmin, self).get_fieldsets(request, obj) + fieldsets[0][1]['fields'].append('general_field') + fieldsets[2][1]['fields'].append('content_field') + fieldsets[3][1]['fields'].append('seo_field') + return fieldsets + + def get_list_display(self, request): + list_display = super(NewsExtendedAdmin, self).get_list_display(request) + list_display.append('seo_field') + return list_display + +admin.site.register(NewsExtended, NewsExtendedAdmin) diff --git a/tests/myapp/fixtures/tests_data.json b/tests/myapp/fixtures/tests_data.json new file mode 100644 index 0000000000000000000000000000000000000000..7b70649815cb535af9c5d7c92a5d95b7c4b9d50d --- /dev/null +++ b/tests/myapp/fixtures/tests_data.json @@ -0,0 +1,632 @@ +[ +{ + "pk": 1, + "model": "myapp.news", + "fields": { + "newsbox_published": true, + "newsbox_slug": "news-1", + "newsbox_creation_date": "2014-03-11T13:54:03.213Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_summary": "Summary of the news 1", + "newsbox_body": "Body of the news 1", + "newsbox_changed_date": "2014-03-11T13:54:03.213Z", + "newsbox_title": "News 1" + } +}, +{ + "pk": 2, + "model": "myapp.news", + "fields": { + "newsbox_published": false, + "newsbox_slug": "news-2", + "newsbox_creation_date": "2014-03-11T13:54:03.398Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_summary": "Summary of the news 2", + "newsbox_body": "Body of the news 2", + "newsbox_changed_date": "2014-03-11T13:54:03.398Z", + "newsbox_title": "News 2" + } +}, +{ + "pk": 3, + "model": "myapp.news", + "fields": { + "newsbox_published": true, + "newsbox_slug": "news-3", + "newsbox_creation_date": "2014-03-11T13:54:03.598Z", + "newsbox_publication_start_date": "2020-01-01T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_summary": "Summary of the news 3", + "newsbox_body": "Body of the news 3", + "newsbox_changed_date": "2014-03-11T13:54:03.598Z", + "newsbox_title": "News 3" + } +}, +{ + "pk": 4, + "model": "myapp.news", + "fields": { + "newsbox_published": true, + "newsbox_slug": "news-4", + "newsbox_creation_date": "2014-03-11T13:54:03.882Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_summary": "Summary of the news 4", + "newsbox_body": "", + "newsbox_changed_date": "2014-03-11T13:54:03.882Z", + "newsbox_title": "News 4" + } +}, +{ + "pk": 5, + "model": "myapp.news", + "fields": { + "newsbox_published": false, + "newsbox_slug": "news-5", + "newsbox_creation_date": "2014-03-11T13:54:04.083Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_summary": "Summary of the news 5", + "newsbox_body": "Body of the news 5", + "newsbox_changed_date": "2014-03-11T13:54:04.083Z", + "newsbox_title": "News 5" + } +}, +{ + "pk": 6, + "model": "myapp.news", + "fields": { + "newsbox_published": true, + "newsbox_slug": "news-6", + "newsbox_creation_date": "2014-03-11T13:54:04.293Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2005-07-15T08:00:00Z", + "newsbox_summary": "Summary of the news 6", + "newsbox_body": "Body of the news 6", + "newsbox_changed_date": "2014-03-11T13:54:04.293Z", + "newsbox_title": "News 6" + } +}, +{ + "pk": 7, + "model": "myapp.news", + "fields": { + "newsbox_published": true, + "newsbox_slug": "news-7", + "newsbox_creation_date": "2014-03-11T13:54:04.502Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2020-01-01T08:00:00Z", + "newsbox_summary": "Summary of the news 7", + "newsbox_body": "Body of the news 7", + "newsbox_changed_date": "2014-03-11T13:54:04.503Z", + "newsbox_title": "News 7" + } +}, +{ + "pk": 1, + "model": "myapp.newsseo", + "fields": { + "newsbox_published": true, + "newsbox_meta_description": "Meta description of the news 1", + "newsbox_slug": "news-1", + "newsbox_creation_date": "2014-03-11T13:54:01.813Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-1", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_summary": "Summary of the news 1", + "newsbox_body": "Body of the news 1", + "newsbox_changed_date": "2014-03-11T13:54:01.813Z", + "newsbox_title": "News 1" + } +}, +{ + "pk": 2, + "model": "myapp.newsseo", + "fields": { + "newsbox_published": false, + "newsbox_meta_description": "Meta description of the news 2", + "newsbox_slug": "news-2", + "newsbox_creation_date": "2014-03-11T13:54:02.005Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-2", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_summary": "Summary of the news 2", + "newsbox_body": "Body of the news 2", + "newsbox_changed_date": "2014-03-11T13:54:02.005Z", + "newsbox_title": "News 2" + } +}, +{ + "pk": 3, + "model": "myapp.newsseo", + "fields": { + "newsbox_published": true, + "newsbox_meta_description": "Meta description of the news 3", + "newsbox_slug": "news-3", + "newsbox_creation_date": "2014-03-11T13:54:02.201Z", + "newsbox_publication_start_date": "2020-01-01T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-3", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_summary": "Summary of the news 3", + "newsbox_body": "Body of the news 3", + "newsbox_changed_date": "2014-03-11T13:54:02.201Z", + "newsbox_title": "News 3" + } +}, +{ + "pk": 4, + "model": "myapp.newsseo", + "fields": { + "newsbox_published": true, + "newsbox_meta_description": "Meta description of the news 4", + "newsbox_slug": "news-4", + "newsbox_creation_date": "2014-03-11T13:54:02.408Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-4", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_summary": "Summary of the news 4", + "newsbox_body": "", + "newsbox_changed_date": "2014-03-11T13:54:02.408Z", + "newsbox_title": "News 4" + } +}, +{ + "pk": 5, + "model": "myapp.newsseo", + "fields": { + "newsbox_published": false, + "newsbox_meta_description": "Meta description of the news 5", + "newsbox_slug": "news-5", + "newsbox_creation_date": "2014-03-11T13:54:02.602Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-5", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_summary": "Summary of the news 5", + "newsbox_body": "Body of the news 5", + "newsbox_changed_date": "2014-03-11T13:54:02.602Z", + "newsbox_title": "News 5" + } +}, +{ + "pk": 6, + "model": "myapp.newsseo", + "fields": { + "newsbox_published": true, + "newsbox_meta_description": "Meta description of the news 6", + "newsbox_slug": "news-6", + "newsbox_creation_date": "2014-03-11T13:54:02.810Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-6", + "newsbox_date": "2005-07-15T08:00:00Z", + "newsbox_indexed": false, + "newsbox_summary": "Summary of the news 6", + "newsbox_body": "Body of the news 6", + "newsbox_changed_date": "2014-03-11T13:54:02.810Z", + "newsbox_title": "News 6" + } +}, +{ + "pk": 7, + "model": "myapp.newsseo", + "fields": { + "newsbox_published": true, + "newsbox_meta_description": "Meta description of the news 7", + "newsbox_slug": "news-7", + "newsbox_creation_date": "2014-03-11T13:54:03.019Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-7", + "newsbox_date": "2020-01-01T08:00:00Z", + "newsbox_indexed": true, + "newsbox_summary": "Summary of the news 7", + "newsbox_body": "Body of the news 7", + "newsbox_changed_date": "2014-03-11T13:54:03.019Z", + "newsbox_title": "News 7" + } +}, +{ + "pk": 1, + "model": "myapp.newsexpired", + "fields": { + "newsbox_published": true, + "newsbox_slug": "news-1", + "newsbox_changed_date": "2014-03-11T13:53:50.409Z", + "newsbox_creation_date": "2014-03-11T13:53:50.409Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_summary": "Summary of the news 1", + "newsbox_body": "Body of the news 1", + "newsbox_publication_end_date": null, + "newsbox_title": "News 1" + } +}, +{ + "pk": 2, + "model": "myapp.newsexpired", + "fields": { + "newsbox_published": false, + "newsbox_slug": "news-2", + "newsbox_changed_date": "2014-03-11T13:53:50.593Z", + "newsbox_creation_date": "2014-03-11T13:53:50.593Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_summary": "Summary of the news 2", + "newsbox_body": "Body of the news 2", + "newsbox_publication_end_date": null, + "newsbox_title": "News 2" + } +}, +{ + "pk": 3, + "model": "myapp.newsexpired", + "fields": { + "newsbox_published": true, + "newsbox_slug": "news-3", + "newsbox_changed_date": "2014-03-11T13:53:50.795Z", + "newsbox_creation_date": "2014-03-11T13:53:50.795Z", + "newsbox_publication_start_date": "2020-01-01T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_summary": "Summary of the news 3", + "newsbox_body": "Body of the news 3", + "newsbox_publication_end_date": null, + "newsbox_title": "News 3" + } +}, +{ + "pk": 4, + "model": "myapp.newsexpired", + "fields": { + "newsbox_published": true, + "newsbox_slug": "news-4", + "newsbox_changed_date": "2014-03-11T13:53:50.988Z", + "newsbox_creation_date": "2014-03-11T13:53:50.988Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_summary": "Summary of the news 4", + "newsbox_body": "", + "newsbox_publication_end_date": null, + "newsbox_title": "News 4" + } +}, +{ + "pk": 5, + "model": "myapp.newsexpired", + "fields": { + "newsbox_published": true, + "newsbox_slug": "news-5", + "newsbox_changed_date": "2014-03-11T13:53:51.196Z", + "newsbox_creation_date": "2014-03-11T13:53:51.196Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_summary": "Summary of the news 5", + "newsbox_body": "Body of the news 5", + "newsbox_publication_end_date": "2000-01-01T08:00:00Z", + "newsbox_title": "News 5" + } +}, +{ + "pk": 6, + "model": "myapp.newsexpired", + "fields": { + "newsbox_published": true, + "newsbox_slug": "news-6", + "newsbox_changed_date": "2014-03-11T13:53:51.406Z", + "newsbox_creation_date": "2014-03-11T13:53:51.406Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2005-07-15T08:00:00Z", + "newsbox_summary": "Summary of the news 6", + "newsbox_body": "Body of the news 6", + "newsbox_publication_end_date": null, + "newsbox_title": "News 6" + } +}, +{ + "pk": 7, + "model": "myapp.newsexpired", + "fields": { + "newsbox_published": true, + "newsbox_slug": "news-7", + "newsbox_changed_date": "2014-03-11T13:53:51.589Z", + "newsbox_creation_date": "2014-03-11T13:53:51.589Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2020-01-01T08:00:00Z", + "newsbox_summary": "Summary of the news 7", + "newsbox_body": "Body of the news 7", + "newsbox_publication_end_date": null, + "newsbox_title": "News 7" + } +}, +{ + "pk": 1, + "model": "myapp.newscomplete", + "fields": { + "newsbox_published": true, + "newsbox_meta_description": "Meta description of the news 1", + "newsbox_slug": "news-1", + "newsbox_changed_date": "2014-03-11T13:53:28.605Z", + "newsbox_creation_date": "2014-03-11T13:53:28.605Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-1", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_summary": "Summary of the news 1", + "newsbox_body": "Body of the news 1", + "newsbox_publication_end_date": null, + "newsbox_title": "News 1" + } +}, +{ + "pk": 2, + "model": "myapp.newscomplete", + "fields": { + "newsbox_published": false, + "newsbox_meta_description": "Meta description of the news 2", + "newsbox_slug": "news-2", + "newsbox_changed_date": "2014-03-11T13:53:28.763Z", + "newsbox_creation_date": "2014-03-11T13:53:28.763Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-2", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_summary": "Summary of the news 2", + "newsbox_body": "Body of the news 2", + "newsbox_publication_end_date": null, + "newsbox_title": "News 2" + } +}, +{ + "pk": 3, + "model": "myapp.newscomplete", + "fields": { + "newsbox_published": true, + "newsbox_meta_description": "Meta description of the news 3", + "newsbox_slug": "news-3", + "newsbox_changed_date": "2014-03-11T13:53:28.947Z", + "newsbox_creation_date": "2014-03-11T13:53:28.947Z", + "newsbox_publication_start_date": "2020-01-01T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-3", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_summary": "Summary of the news 3", + "newsbox_body": "Body of the news 3", + "newsbox_publication_end_date": null, + "newsbox_title": "News 3" + } +}, +{ + "pk": 4, + "model": "myapp.newscomplete", + "fields": { + "newsbox_published": true, + "newsbox_meta_description": "Meta description of the news 4", + "newsbox_slug": "news-4", + "newsbox_changed_date": "2014-03-11T13:53:29.125Z", + "newsbox_creation_date": "2014-03-11T13:53:29.125Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-4", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_summary": "Summary of the news 4", + "newsbox_body": "", + "newsbox_publication_end_date": null, + "newsbox_title": "News 4" + } +}, +{ + "pk": 5, + "model": "myapp.newscomplete", + "fields": { + "newsbox_published": false, + "newsbox_meta_description": "Meta description of the news 5", + "newsbox_slug": "news-5", + "newsbox_changed_date": "2014-03-11T13:53:29.368Z", + "newsbox_creation_date": "2014-03-11T13:53:29.368Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-5", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_summary": "Summary of the news 5", + "newsbox_body": "Body of the news 5", + "newsbox_publication_end_date": "2000-01-01T08:00:00Z", + "newsbox_title": "News 5" + } +}, +{ + "pk": 6, + "model": "myapp.newscomplete", + "fields": { + "newsbox_published": true, + "newsbox_meta_description": "Meta description of the news 6", + "newsbox_slug": "news-6", + "newsbox_changed_date": "2014-03-11T13:53:29.594Z", + "newsbox_creation_date": "2014-03-11T13:53:29.594Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-6", + "newsbox_date": "2005-07-15T08:00:00Z", + "newsbox_indexed": false, + "newsbox_summary": "Summary of the news 6", + "newsbox_body": "Body of the news 6", + "newsbox_publication_end_date": null, + "newsbox_title": "News 6" + } +}, +{ + "pk": 7, + "model": "myapp.newscomplete", + "fields": { + "newsbox_published": true, + "newsbox_meta_description": "Meta description of the news 7", + "newsbox_slug": "news-7", + "newsbox_changed_date": "2014-03-11T13:53:29.787Z", + "newsbox_creation_date": "2014-03-11T13:53:29.787Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-7", + "newsbox_date": "2020-01-01T08:00:00Z", + "newsbox_indexed": true, + "newsbox_summary": "Summary of the news 7", + "newsbox_body": "Body of the news 7", + "newsbox_publication_end_date": null, + "newsbox_title": "News 7" + } +}, +{ + "pk": 1, + "model": "myapp.newsextended", + "fields": { + "newsbox_published": true, + "content_field": "Extra content of the news 1", + "newsbox_slug": "news-1", + "newsbox_changed_date": "2014-03-11T13:53:49.052Z", + "newsbox_creation_date": "2014-03-11T13:53:49.052Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-1", + "newsbox_date": "2014-02-22T08:00:00Z", + "general_field": "Test", + "newsbox_indexed": true, + "seo_field": "Extra SEO of the news 1", + "newsbox_summary": "Summary of the news 1", + "newsbox_meta_description": "Meta description of the news 1", + "newsbox_body": "Body of the news 1", + "newsbox_publication_end_date": null, + "newsbox_title": "News 1" + } +}, +{ + "pk": 2, + "model": "myapp.newsextended", + "fields": { + "newsbox_published": false, + "content_field": "Extra content of the news 2", + "newsbox_slug": "news-2", + "newsbox_changed_date": "2014-03-11T13:53:49.243Z", + "newsbox_creation_date": "2014-03-11T13:53:49.243Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-2", + "newsbox_date": "2014-02-22T08:00:00Z", + "general_field": "Test", + "newsbox_indexed": true, + "seo_field": "Extra SEO of the news 2", + "newsbox_summary": "Summary of the news 2", + "newsbox_meta_description": "Meta description of the news 2", + "newsbox_body": "Body of the news 2", + "newsbox_publication_end_date": null, + "newsbox_title": "News 2" + } +}, +{ + "pk": 3, + "model": "myapp.newsextended", + "fields": { + "newsbox_published": true, + "content_field": "Extra content of the news 3", + "newsbox_slug": "news-3", + "newsbox_changed_date": "2014-03-11T13:53:49.445Z", + "newsbox_creation_date": "2014-03-11T13:53:49.445Z", + "newsbox_publication_start_date": "2020-01-01T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-3", + "newsbox_date": "2014-02-22T08:00:00Z", + "general_field": "Test", + "newsbox_indexed": true, + "seo_field": "Extra SEO of the news 3", + "newsbox_summary": "Summary of the news 3", + "newsbox_meta_description": "Meta description of the news 3", + "newsbox_body": "Body of the news 3", + "newsbox_publication_end_date": null, + "newsbox_title": "News 3" + } +}, +{ + "pk": 4, + "model": "myapp.newsextended", + "fields": { + "newsbox_published": true, + "content_field": "Extra content of the news 4", + "newsbox_slug": "news-4", + "newsbox_changed_date": "2014-03-11T13:53:49.629Z", + "newsbox_creation_date": "2014-03-11T13:53:49.629Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-4", + "newsbox_date": "2014-02-22T08:00:00Z", + "general_field": "Test", + "newsbox_indexed": true, + "seo_field": "Extra SEO of the news 4", + "newsbox_summary": "Summary of the news 4", + "newsbox_meta_description": "Meta description of the news 4", + "newsbox_body": "", + "newsbox_publication_end_date": null, + "newsbox_title": "News 4" + } +}, +{ + "pk": 5, + "model": "myapp.newsextended", + "fields": { + "newsbox_published": false, + "content_field": "Extra content of the news 5", + "newsbox_slug": "news-5", + "newsbox_changed_date": "2014-03-11T13:53:49.830Z", + "newsbox_creation_date": "2014-03-11T13:53:49.830Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-5", + "newsbox_date": "2014-02-22T08:00:00Z", + "general_field": "Test", + "newsbox_indexed": true, + "seo_field": "Extra SEO of the news 5", + "newsbox_summary": "Summary of the news 5", + "newsbox_meta_description": "Meta description of the news 5", + "newsbox_body": "Body of the news 5", + "newsbox_publication_end_date": "2000-01-01T08:00:00Z", + "newsbox_title": "News 5" + } +}, +{ + "pk": 6, + "model": "myapp.newsextended", + "fields": { + "newsbox_published": true, + "content_field": "Extra content of the news 6", + "newsbox_slug": "news-6", + "newsbox_changed_date": "2014-03-11T13:53:50.016Z", + "newsbox_creation_date": "2014-03-11T13:53:50.016Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-6", + "newsbox_date": "2005-07-15T08:00:00Z", + "general_field": "Test", + "newsbox_indexed": false, + "seo_field": "Extra SEO of the news 6", + "newsbox_summary": "Summary of the news 6", + "newsbox_meta_description": "Meta description of the news 6", + "newsbox_body": "Body of the news 6", + "newsbox_publication_end_date": null, + "newsbox_title": "News 6" + } +}, +{ + "pk": 7, + "model": "myapp.newsextended", + "fields": { + "newsbox_published": true, + "content_field": "Extra content of the news 7", + "newsbox_slug": "news-7", + "newsbox_changed_date": "2014-03-11T13:53:50.208Z", + "newsbox_creation_date": "2014-03-11T13:53:50.208Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-7", + "newsbox_date": "2020-01-01T08:00:00Z", + "general_field": "Test", + "newsbox_indexed": true, + "seo_field": "Extra SEO of the news 7", + "newsbox_summary": "Summary of the news 7", + "newsbox_meta_description": "Meta description of the news 7", + "newsbox_body": "Body of the news 7", + "newsbox_publication_end_date": null, + "newsbox_title": "News 7" + } +} +] diff --git a/tests/myapp/models.py b/tests/myapp/models.py new file mode 100644 index 0000000000000000000000000000000000000000..eddc3fd82ca67fe2ca4c24a85aeebb2f82385c32 --- /dev/null +++ b/tests/myapp/models.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from django.db import models +from newsbox.models import NewsboxBase, NewsboxSEOBase, NewsboxExpiredBase + +class News(NewsboxBase): + class Meta: + verbose_name = 'news - Basic' + verbose_name_plural = 'news - Basic' + +class NewsSEO(NewsboxBase, NewsboxSEOBase): + class Meta: + verbose_name = 'news - SEO' + verbose_name_plural = 'news - SEO' + +class NewsExpired(NewsboxBase, NewsboxExpiredBase): + class Meta: + verbose_name = 'news - Expirable' + verbose_name_plural = 'news - Expirable' + +class NewsComplete(NewsboxBase, NewsboxSEOBase, NewsboxExpiredBase): + class Meta: + verbose_name = 'news - Complete' + verbose_name_plural = 'news - Complete' + +class NewsExtended(NewsboxBase, NewsboxSEOBase, NewsboxExpiredBase): + general_field = models.CharField(max_length=50) + content_field = models.CharField(max_length=50) + seo_field = models.CharField(max_length=50) + + class Meta: + verbose_name = 'news - Extended' + verbose_name_plural = 'news - Extended' diff --git a/tests/myapp/tests.py b/tests/myapp/tests.py new file mode 100644 index 0000000000000000000000000000000000000000..e9ca0137a6e480e9cd0bcd97eb82fd7ad834c9be --- /dev/null +++ b/tests/myapp/tests.py @@ -0,0 +1,174 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from django.test import TestCase, Client +from django.core.paginator import EmptyPage +from bs4 import BeautifulSoup +from .models import News, NewsSEO, NewsExpired, NewsComplete, NewsExtended + + +class NewsboxAbstractModelsTests(TestCase): + + fixtures = ['tests_data.json',] + + def test_01_manager_published(self): + """ + Test if we only get really published news via the manager + """ + newsClasses = [ + News, NewsSEO, NewsExpired, NewsComplete, NewsExtended, + ] + for cls in newsClasses: + returned_ids = list(cls.objects.published().values_list( + 'id', flat=True).order_by('id')) + self.assertEqual( + (cls.__name__,returned_ids), + (cls.__name__,[1, 4, 6, 7,])) + + def test_02_view_archive_200(self): + """ + Test if generic archive view return right informations. + """ + c = Client() + r = c.get('/news/') + + self.assertEqual(r.status_code, 200) + self.assertIn('newsset', r.context) + self.assertEqual(r.context['newsset'][0].pk, 7) + self.assertEqual(r.context['newsset'].number, 1) + self.assertEqual(r.context['newsset'].paginator.num_pages, 4) + self.assertFalse(r.context['newsset'].has_previous()) + self.assertTrue(r.context['newsset'].has_next()) + self.assertRaises(EmptyPage, r.context['newsset'].previous_page_number) + self.assertEqual(r.context['newsset'].next_page_number(), 2) + + + def test_03_view_year_archive_200(self): + """ + Test if generic year views return right informations. + """ + c = Client() + r = c.get('/news/2005/') + self.assertEqual(r.status_code, 200) + self.assertEqual(r.context['newsset'][0].pk, 6) + self.assertFalse(r.context['with_pager']) + r = c.get('/news/2014/') + self.assertEqual(r.status_code, 200) + self.assertEqual(r.context['newsset'].paginator.num_pages, 2) + r = c.get('/news/2020/') + self.assertEqual(r.status_code, 200) + self.assertEqual(r.context['newsset'].paginator.num_pages, 1) + + def test_04_view_year_archive_404(self): + """ + Test if generic year views return a 404 with an URL with a year without + any news. + """ + c = Client() + r = c.get('/newsbox/myapp/news/1985/') + self.assertEqual(r.status_code, 404) + + def test_05_view_month_archive_200(self): + """ + Test if generic month views return right informations. + """ + c = Client() + r = c.get('/newsbox/myapp/news/2005/07/') + self.assertEqual(r.status_code, 200) + ref = c.get('/newsbox/myapp/news/2005/') + self.assertEqual(r.content, ref.content) + + def test_06_view_month_archive_404(self): + """ + Test if generic month views return a 404 with an URL with a year + month + without any news. + """ + c = Client() + r = c.get('/newsbox/myapp/news/1985/07/') + self.assertEqual(r.status_code, 404) + + def test_07_view_day_archive_200(self): + """ + Test if generic day views return right informations. + """ + c = Client() + r = c.get('/newsbox/myapp/news/2005/07/15/') + self.assertEqual(r.status_code, 200) + ref = c.get('/newsbox/myapp/news/2005/07/') + self.assertEqual(r.content, ref.content) + + def test_08_view_month_archive_404(self): + """ + Test if generic day views return a 404 with an URL with a date without + any news. + """ + c = Client() + r = c.get('/newsbox/myapp/news/1985/07/02/') + self.assertEqual(r.status_code, 404) + + def test_09_view_detail_200(self): + """ + Test if generic day views return right informations. + """ + c = Client() + r = c.get('/newsbox/myapp/news/2005/07/15/news-6/') + self.assertEqual(r.status_code, 200) + self.assertEqual(r.context['news'].pk, 6) + + def test_10_view_detail_404(self): + """ + Test if generic day views return a 404 with an URL with a date without + any news. + """ + c = Client() + r = c.get('/newsbox/myapp/news/1985/07/02/my-birthday/') + self.assertEqual(r.status_code, 404) + + def test_11_view_detail_404_not_published(self): + """ + Test if generic day views return a 404 with an URL with a not published + news + """ + c = Client() + r = c.get('/newsbox/myapp/news/2014/02/22/news-2/') + self.assertEqual(r.status_code, 404) + + def has_readmore_link(self, news): + readmore_p = news.find('p', class_='readmore') + if readmore_p: + readmore_a = readmore_p.find('a') + if readmore_a: + return True + + return False + + def get_news_in_list_by_summary(self, response, summary): + soup = BeautifulSoup(response.content) + for news in soup.find_all('div', class_='news'): + readmore_summary = news.find('p', text=summary) + if readmore_summary: + return news + return None + + def test_news_4_has_no_readmore_link(self): + """ + Test if readmore link is not present in news 4 + """ + c = Client() + r = c.get('/news/?page=2') + news = self.get_news_in_list_by_summary(r, u'Summary of the news 4') + self.assertIsNotNone(news) + + found = self.has_readmore_link(news) + self.assertFalse(found) + + def test_news_6_has_readmore_link(self): + """ + Test if readmore link is present in news 6 + """ + c = Client() + r = c.get('/news/2005/') + news = self.get_news_in_list_by_summary(r, u'Summary of the news 6') + self.assertIsNotNone(news) + + found = self.has_readmore_link(news) + self.assertTrue(found) diff --git a/tests/myapp/urls.py b/tests/myapp/urls.py new file mode 100644 index 0000000000000000000000000000000000000000..ddb3e6932166578a67fdba119c96fd9ad30e8a3b --- /dev/null +++ b/tests/myapp/urls.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.conf.urls import url, include, patterns +from django.contrib import admin +from django.conf import settings +from newsbox.views import NewsboxYearArchiveView, NewsboxArchiveView + +from .models import News + +admin.autodiscover() + +urlpatterns = patterns('', + url(r'^admin/', include(admin.site.urls)), + url(r'^', include('newsbox.urls')), + url(r'^news/$', + NewsboxArchiveView.as_view(model=News, paginate_by=1), + name='news_list',), + url(r'^news/(?P<year>\d{4})/$', + NewsboxYearArchiveView.as_view(model=News, paginate_by=1), + name='news_list_y',), +) diff --git a/tests/myapp_all/__init__.py b/tests/myapp_all/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..40a96afc6ff09d58a702b76e3f7dd412fe975e26 --- /dev/null +++ b/tests/myapp_all/__init__.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*- diff --git a/tests/myapp_all/admin.py b/tests/myapp_all/admin.py new file mode 100644 index 0000000000000000000000000000000000000000..95ff7bb7784ef79cc2ea61b1e867ed6d45a623f8 --- /dev/null +++ b/tests/myapp_all/admin.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals + +from django.contrib import admin +from newsbox_cms.admin import NewsboxCMSAdmin +from newsbox.admin import NewsboxSEOAdmin, NewsboxExpiredAdmin +from newsbox_hvad.admin import NewsboxHVADAdmin + +from .models import News, NewsComplete, NewsExtended + +class NewsAdmin(NewsboxHVADAdmin, NewsboxCMSAdmin): + pass + +admin.site.register(News, NewsAdmin) + + +class NewsCompleteAdmin(NewsboxHVADAdmin, NewsboxCMSAdmin, NewsboxSEOAdmin, NewsboxExpiredAdmin): + pass + +admin.site.register(NewsComplete, NewsCompleteAdmin) + + +class NewsExtendedAdmin(NewsboxHVADAdmin, NewsboxCMSAdmin, NewsboxSEOAdmin, NewsboxExpiredAdmin): + def get_fieldsets(self, request, obj=None): + fieldsets = super(NewsExtendedAdmin, self).get_fieldsets(request, obj) + fieldsets[0][1]['fields'].append('general_field') + fieldsets[2][1]['fields'].append('content_field') + fieldsets[3][1]['fields'].append('seo_field') + return fieldsets + + def get_list_display(self, request): + list_display = super(NewsExtendedAdmin, self).get_list_display(request) + list_display.append('seo_field') + return list_display + +admin.site.register(NewsExtended, NewsExtendedAdmin) diff --git a/tests/myapp_all/cms_app.py b/tests/myapp_all/cms_app.py new file mode 100644 index 0000000000000000000000000000000000000000..d25c3bee48b54eb42e1f5658856af3e60b9e806c --- /dev/null +++ b/tests/myapp_all/cms_app.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals + +from cms.app_base import CMSApp +from cms.apphook_pool import apphook_pool + +class NewsApphook(CMSApp): + name = 'News' + urls = ["myapp_all.urls_news"] + +apphook_pool.register(NewsApphook) diff --git a/tests/myapp_all/cms_plugins.py b/tests/myapp_all/cms_plugins.py new file mode 100644 index 0000000000000000000000000000000000000000..ae203265d409663e0a02c615dbd2a1c312a9aa2b --- /dev/null +++ b/tests/myapp_all/cms_plugins.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals + +from cms.plugin_pool import plugin_pool +from newsbox_cms.cms_plugins import NewsboxPluginBase + +from .models import NewsPlugin as NewsPluginModel + + +class NewsPlugin(NewsboxPluginBase): + name = "News list ALL" # Name of the plugin + model = NewsPluginModel + +plugin_pool.register_plugin(NewsPlugin) diff --git a/tests/myapp_all/fixtures/tests_data.json b/tests/myapp_all/fixtures/tests_data.json new file mode 100644 index 0000000000000000000000000000000000000000..d81809eec81375f4ee57481426c703bcffa393a0 --- /dev/null +++ b/tests/myapp_all/fixtures/tests_data.json @@ -0,0 +1,835 @@ +[ +{ + "pk": 1, + "model": "myapp_all.newstranslation", + "fields": { + "language_code": "en", + "master": 1, + "newsbox_slug": "news-1", + "newsbox_title": "News 1", + "newsbox_summary": "<p>Summary of the news 1</p>" + } +}, +{ + "pk": 2, + "model": "myapp_all.newstranslation", + "fields": { + "language_code": "fr", + "master": 1, + "newsbox_slug": "actualite-1", + "newsbox_title": "Actualit\u00e9 1", + "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 1</p>" + } +}, +{ + "pk": 3, + "model": "myapp_all.newstranslation", + "fields": { + "language_code": "en", + "master": 2, + "newsbox_slug": "news-2", + "newsbox_title": "News 2", + "newsbox_summary": "<p>Summary of the news 2</p>" + } +}, +{ + "pk": 4, + "model": "myapp_all.newstranslation", + "fields": { + "language_code": "fr", + "master": 2, + "newsbox_slug": "actualite-2", + "newsbox_title": "Actualit\u00e9 2", + "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 2</p>" + } +}, +{ + "pk": 5, + "model": "myapp_all.newstranslation", + "fields": { + "language_code": "en", + "master": 3, + "newsbox_slug": "news-3", + "newsbox_title": "News 3", + "newsbox_summary": "<p>Summary of the news 3</p>" + } +}, +{ + "pk": 6, + "model": "myapp_all.newstranslation", + "fields": { + "language_code": "fr", + "master": 3, + "newsbox_slug": "actualite-3", + "newsbox_title": "Actualit\u00e9 3", + "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 3</p>" + } +}, +{ + "pk": 7, + "model": "myapp_all.newstranslation", + "fields": { + "language_code": "en", + "master": 4, + "newsbox_slug": "news-4", + "newsbox_title": "News 4", + "newsbox_summary": "<p>Summary of the news 4</p>" + } +}, +{ + "pk": 8, + "model": "myapp_all.newstranslation", + "fields": { + "language_code": "fr", + "master": 4, + "newsbox_slug": "actualite-4", + "newsbox_title": "Actualit\u00e9 4", + "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 4</p>" + } +}, +{ + "pk": 9, + "model": "myapp_all.newstranslation", + "fields": { + "language_code": "en", + "master": 5, + "newsbox_slug": "news-5", + "newsbox_title": "News 5", + "newsbox_summary": "<p>Summary of the news 5</p>" + } +}, +{ + "pk": 10, + "model": "myapp_all.newstranslation", + "fields": { + "language_code": "fr", + "master": 5, + "newsbox_slug": "actualite-5", + "newsbox_title": "Actualit\u00e9 5", + "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 5</p>" + } +}, +{ + "pk": 11, + "model": "myapp_all.newstranslation", + "fields": { + "language_code": "en", + "master": 6, + "newsbox_slug": "news-6", + "newsbox_title": "News 6", + "newsbox_summary": "<p>Summary of the news 6</p>" + } +}, +{ + "pk": 12, + "model": "myapp_all.newstranslation", + "fields": { + "language_code": "fr", + "master": 6, + "newsbox_slug": "actualite-6", + "newsbox_title": "Actualit\u00e9 6", + "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 6</p>" + } +}, +{ + "pk": 13, + "model": "myapp_all.newstranslation", + "fields": { + "language_code": "en", + "master": 7, + "newsbox_slug": "news-7", + "newsbox_title": "News 7", + "newsbox_summary": "<p>Summary of the news 7</p>" + } +}, +{ + "pk": 14, + "model": "myapp_all.newstranslation", + "fields": { + "language_code": "fr", + "master": 7, + "newsbox_slug": "actualite-7", + "newsbox_title": "Actualit\u00e9 7", + "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 7</p>" + } +}, +{ + "pk": 1, + "model": "myapp_all.news", + "fields": { + "newsbox_published": true, + "newsbox_creation_date": "2014-03-29T14:22:26.190Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_body": 24, + "newsbox_changed_date": "2014-03-29T14:22:26.717Z" + } +}, +{ + "pk": 2, + "model": "myapp_all.news", + "fields": { + "newsbox_published": false, + "newsbox_creation_date": "2014-03-29T14:22:27.254Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_body": 27, + "newsbox_changed_date": "2014-03-29T14:22:27.782Z" + } +}, +{ + "pk": 3, + "model": "myapp_all.news", + "fields": { + "newsbox_published": true, + "newsbox_creation_date": "2014-03-29T14:22:28.279Z", + "newsbox_publication_start_date": "2020-01-01T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_body": 30, + "newsbox_changed_date": "2014-03-29T14:22:28.907Z" + } +}, +{ + "pk": 4, + "model": "myapp_all.news", + "fields": { + "newsbox_published": true, + "newsbox_creation_date": "2014-03-29T14:22:29.718Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_body": 33, + "newsbox_changed_date": "2014-03-29T14:22:30.273Z" + } +}, +{ + "pk": 5, + "model": "myapp_all.news", + "fields": { + "newsbox_published": false, + "newsbox_creation_date": "2014-03-29T14:22:30.760Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_body": 36, + "newsbox_changed_date": "2014-03-29T14:22:31.355Z" + } +}, +{ + "pk": 6, + "model": "myapp_all.news", + "fields": { + "newsbox_published": true, + "newsbox_creation_date": "2014-03-29T14:22:31.842Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2005-07-15T08:00:00Z", + "newsbox_body": 39, + "newsbox_changed_date": "2014-03-29T14:22:32.397Z" + } +}, +{ + "pk": 7, + "model": "myapp_all.news", + "fields": { + "newsbox_published": true, + "newsbox_creation_date": "2014-03-29T14:22:32.892Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2020-01-01T08:00:00Z", + "newsbox_body": 42, + "newsbox_changed_date": "2014-03-29T14:22:33.428Z" + } +}, +{ + "pk": 1, + "model": "myapp_all.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-1", + "newsbox_slug": "news-1", + "newsbox_meta_description": "Meta description of the news 1", + "master": 1, + "newsbox_summary": "<p>Summary of the news 1</p>", + "language_code": "en", + "newsbox_title": "News 1" + } +}, +{ + "pk": 2, + "model": "myapp_all.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-1", + "newsbox_slug": "actualite-1", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 1", + "master": 1, + "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 1</p>", + "language_code": "fr", + "newsbox_title": "Actualit\u00e9 1" + } +}, +{ + "pk": 3, + "model": "myapp_all.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-2", + "newsbox_slug": "news-2", + "newsbox_meta_description": "Meta description of the news 2", + "master": 2, + "newsbox_summary": "<p>Summary of the news 2</p>", + "language_code": "en", + "newsbox_title": "News 2" + } +}, +{ + "pk": 4, + "model": "myapp_all.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-2", + "newsbox_slug": "actualite-2", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 2", + "master": 2, + "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 2</p>", + "language_code": "fr", + "newsbox_title": "Actualit\u00e9 2" + } +}, +{ + "pk": 5, + "model": "myapp_all.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-3", + "newsbox_slug": "news-3", + "newsbox_meta_description": "Meta description of the news 3", + "master": 3, + "newsbox_summary": "<p>Summary of the news 3</p>", + "language_code": "en", + "newsbox_title": "News 3" + } +}, +{ + "pk": 6, + "model": "myapp_all.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-3", + "newsbox_slug": "actualite-3", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 3", + "master": 3, + "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 3</p>", + "language_code": "fr", + "newsbox_title": "Actualit\u00e9 3" + } +}, +{ + "pk": 7, + "model": "myapp_all.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-4", + "newsbox_slug": "news-4", + "newsbox_meta_description": "Meta description of the news 4", + "master": 4, + "newsbox_summary": "<p>Summary of the news 4</p>", + "language_code": "en", + "newsbox_title": "News 4" + } +}, +{ + "pk": 8, + "model": "myapp_all.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-4", + "newsbox_slug": "actualite-4", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 4", + "master": 4, + "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 4</p>", + "language_code": "fr", + "newsbox_title": "Actualit\u00e9 4" + } +}, +{ + "pk": 9, + "model": "myapp_all.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-5", + "newsbox_slug": "news-5", + "newsbox_meta_description": "Meta description of the news 5", + "master": 5, + "newsbox_summary": "<p>Summary of the news 5</p>", + "language_code": "en", + "newsbox_title": "News 5" + } +}, +{ + "pk": 10, + "model": "myapp_all.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-5", + "newsbox_slug": "actualite-5", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 5", + "master": 5, + "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 5</p>", + "language_code": "fr", + "newsbox_title": "Actualit\u00e9 5" + } +}, +{ + "pk": 11, + "model": "myapp_all.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-6", + "newsbox_slug": "news-6", + "newsbox_meta_description": "Meta description of the news 6", + "master": 6, + "newsbox_summary": "<p>Summary of the news 6</p>", + "language_code": "en", + "newsbox_title": "News 6" + } +}, +{ + "pk": 12, + "model": "myapp_all.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-6", + "newsbox_slug": "actualite-6", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 6", + "master": 6, + "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 6</p>", + "language_code": "fr", + "newsbox_title": "Actualit\u00e9 6" + } +}, +{ + "pk": 13, + "model": "myapp_all.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-7", + "newsbox_slug": "news-7", + "newsbox_meta_description": "Meta description of the news 7", + "master": 7, + "newsbox_summary": "<p>Summary of the news 7</p>", + "language_code": "en", + "newsbox_title": "News 7" + } +}, +{ + "pk": 14, + "model": "myapp_all.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-7", + "newsbox_slug": "actualite-7", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 7", + "master": 7, + "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 7</p>", + "language_code": "fr", + "newsbox_title": "Actualit\u00e9 7" + } +}, +{ + "pk": 1, + "model": "myapp_all.newscomplete", + "fields": { + "newsbox_published": true, + "newsbox_changed_date": "2014-03-29T14:22:34.561Z", + "newsbox_creation_date": "2014-03-29T14:22:34.018Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_body": 45, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 2, + "model": "myapp_all.newscomplete", + "fields": { + "newsbox_published": false, + "newsbox_changed_date": "2014-03-29T14:22:35.785Z", + "newsbox_creation_date": "2014-03-29T14:22:35.132Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_body": 48, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 3, + "model": "myapp_all.newscomplete", + "fields": { + "newsbox_published": true, + "newsbox_changed_date": "2014-03-29T14:22:36.926Z", + "newsbox_creation_date": "2014-03-29T14:22:36.389Z", + "newsbox_publication_start_date": "2020-01-01T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_body": 51, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 4, + "model": "myapp_all.newscomplete", + "fields": { + "newsbox_published": true, + "newsbox_changed_date": "2014-03-29T14:22:38.026Z", + "newsbox_creation_date": "2014-03-29T14:22:37.480Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_body": 54, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 5, + "model": "myapp_all.newscomplete", + "fields": { + "newsbox_published": false, + "newsbox_changed_date": "2014-03-29T14:22:39.167Z", + "newsbox_creation_date": "2014-03-29T14:22:38.580Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_body": 57, + "newsbox_publication_end_date": "2000-01-01T08:00:00Z" + } +}, +{ + "pk": 6, + "model": "myapp_all.newscomplete", + "fields": { + "newsbox_published": true, + "newsbox_changed_date": "2014-03-29T14:22:40.374Z", + "newsbox_creation_date": "2014-03-29T14:22:39.779Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2005-07-15T08:00:00Z", + "newsbox_indexed": false, + "newsbox_body": 60, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 7, + "model": "myapp_all.newscomplete", + "fields": { + "newsbox_published": true, + "newsbox_changed_date": "2014-03-29T14:22:41.557Z", + "newsbox_creation_date": "2014-03-29T14:22:40.920Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2020-01-01T08:00:00Z", + "newsbox_indexed": true, + "newsbox_body": 63, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 1, + "model": "myapp_all.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-1", + "content_field": "Extra content of the news 1", + "newsbox_slug": "news-1", + "newsbox_meta_description": "Meta description of the news 1", + "seo_field": "Extra SEO of the news 1", + "master": 1, + "newsbox_summary": "<p>Summary of the news 1</p>", + "language_code": "en", + "newsbox_title": "News 1" + } +}, +{ + "pk": 2, + "model": "myapp_all.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-1", + "content_field": "Contenu additionnel de l'actualit\u00e9 1", + "newsbox_slug": "actualite-1", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 1", + "seo_field": "SEO additionnel de l'actualit\u00e9 1", + "master": 1, + "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 1</p>", + "language_code": "fr", + "newsbox_title": "Actualit\u00e9 1" + } +}, +{ + "pk": 3, + "model": "myapp_all.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-2", + "content_field": "Extra content of the news 2", + "newsbox_slug": "news-2", + "newsbox_meta_description": "Meta description of the news 2", + "seo_field": "Extra SEO of the news 2", + "master": 2, + "newsbox_summary": "<p>Summary of the news 2</p>", + "language_code": "en", + "newsbox_title": "News 2" + } +}, +{ + "pk": 4, + "model": "myapp_all.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-2", + "content_field": "Contenu additionnel de l'actualit\u00e9 2", + "newsbox_slug": "actualite-2", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 2", + "seo_field": "SEO additionnel de l'actualit\u00e9 2", + "master": 2, + "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 2</p>", + "language_code": "fr", + "newsbox_title": "Actualit\u00e9 2" + } +}, +{ + "pk": 5, + "model": "myapp_all.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-3", + "content_field": "Extra content of the news 3", + "newsbox_slug": "news-3", + "newsbox_meta_description": "Meta description of the news 3", + "seo_field": "Extra SEO of the news 3", + "master": 3, + "newsbox_summary": "<p>Summary of the news 3</p>", + "language_code": "en", + "newsbox_title": "News 3" + } +}, +{ + "pk": 6, + "model": "myapp_all.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-3", + "content_field": "Contenu additionnel de l'actualit\u00e9 3", + "newsbox_slug": "actualite-3", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 3", + "seo_field": "SEO additionnel de l'actualit\u00e9 3", + "master": 3, + "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 3</p>", + "language_code": "fr", + "newsbox_title": "Actualit\u00e9 3" + } +}, +{ + "pk": 7, + "model": "myapp_all.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-4", + "content_field": "Extra content of the news 4", + "newsbox_slug": "news-4", + "newsbox_meta_description": "Meta description of the news 4", + "seo_field": "Extra SEO of the news 4", + "master": 4, + "newsbox_summary": "<p>Summary of the news 4</p>", + "language_code": "en", + "newsbox_title": "News 4" + } +}, +{ + "pk": 8, + "model": "myapp_all.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-4", + "content_field": "Contenu additionnel de l'actualit\u00e9 4", + "newsbox_slug": "actualite-4", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 4", + "seo_field": "SEO additionnel de l'actualit\u00e9 4", + "master": 4, + "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 4</p>", + "language_code": "fr", + "newsbox_title": "Actualit\u00e9 4" + } +}, +{ + "pk": 9, + "model": "myapp_all.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-5", + "content_field": "Extra content of the news 5", + "newsbox_slug": "news-5", + "newsbox_meta_description": "Meta description of the news 5", + "seo_field": "Extra SEO of the news 5", + "master": 5, + "newsbox_summary": "<p>Summary of the news 5</p>", + "language_code": "en", + "newsbox_title": "News 5" + } +}, +{ + "pk": 10, + "model": "myapp_all.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-5", + "content_field": "Contenu additionnel de l'actualit\u00e9 5", + "newsbox_slug": "actualite-5", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 5", + "seo_field": "SEO additionnel de l'actualit\u00e9 5", + "master": 5, + "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 5</p>", + "language_code": "fr", + "newsbox_title": "Actualit\u00e9 5" + } +}, +{ + "pk": 11, + "model": "myapp_all.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-6", + "content_field": "Extra content of the news 6", + "newsbox_slug": "news-6", + "newsbox_meta_description": "Meta description of the news 6", + "seo_field": "Extra SEO of the news 6", + "master": 6, + "newsbox_summary": "<p>Summary of the news 6</p>", + "language_code": "en", + "newsbox_title": "News 6" + } +}, +{ + "pk": 12, + "model": "myapp_all.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-6", + "content_field": "Contenu additionnel de l'actualit\u00e9 6", + "newsbox_slug": "actualite-6", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 6", + "seo_field": "SEO additionnel de l'actualit\u00e9 6", + "master": 6, + "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 6</p>", + "language_code": "fr", + "newsbox_title": "Actualit\u00e9 6" + } +}, +{ + "pk": 13, + "model": "myapp_all.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-7", + "content_field": "Extra content of the news 7", + "newsbox_slug": "news-7", + "newsbox_meta_description": "Meta description of the news 7", + "seo_field": "Extra SEO of the news 7", + "master": 7, + "newsbox_summary": "<p>Summary of the news 7</p>", + "language_code": "en", + "newsbox_title": "News 7" + } +}, +{ + "pk": 14, + "model": "myapp_all.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-7", + "content_field": "Contenu additionnel de l'actualit\u00e9 7", + "newsbox_slug": "actualite-7", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 7", + "seo_field": "SEO additionnel de l'actualit\u00e9 7", + "master": 7, + "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 7</p>", + "language_code": "fr", + "newsbox_title": "Actualit\u00e9 7" + } +}, +{ + "pk": 1, + "model": "myapp_all.newsextended", + "fields": { + "newsbox_published": true, + "newsbox_changed_date": "2014-03-29T14:22:18.579Z", + "newsbox_creation_date": "2014-03-29T14:22:18.020Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "general_field": "Test", + "newsbox_indexed": true, + "newsbox_body": 3, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 2, + "model": "myapp_all.newsextended", + "fields": { + "newsbox_published": false, + "newsbox_changed_date": "2014-03-29T14:22:19.795Z", + "newsbox_creation_date": "2014-03-29T14:22:19.234Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "general_field": "Test", + "newsbox_indexed": true, + "newsbox_body": 6, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 3, + "model": "myapp_all.newsextended", + "fields": { + "newsbox_published": true, + "newsbox_changed_date": "2014-03-29T14:22:21.070Z", + "newsbox_creation_date": "2014-03-29T14:22:20.334Z", + "newsbox_publication_start_date": "2020-01-01T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "general_field": "Test", + "newsbox_indexed": true, + "newsbox_body": 9, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 4, + "model": "myapp_all.newsextended", + "fields": { + "newsbox_published": true, + "newsbox_changed_date": "2014-03-29T14:22:22.186Z", + "newsbox_creation_date": "2014-03-29T14:22:21.608Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "general_field": "Test", + "newsbox_indexed": true, + "newsbox_body": 12, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 5, + "model": "myapp_all.newsextended", + "fields": { + "newsbox_published": false, + "newsbox_changed_date": "2014-03-29T14:22:23.352Z", + "newsbox_creation_date": "2014-03-29T14:22:22.748Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "general_field": "Test", + "newsbox_indexed": true, + "newsbox_body": 15, + "newsbox_publication_end_date": "2000-01-01T08:00:00Z" + } +}, +{ + "pk": 6, + "model": "myapp_all.newsextended", + "fields": { + "newsbox_published": true, + "newsbox_changed_date": "2014-03-29T14:22:24.476Z", + "newsbox_creation_date": "2014-03-29T14:22:23.922Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2005-07-15T08:00:00Z", + "general_field": "Test", + "newsbox_indexed": false, + "newsbox_body": 18, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 7, + "model": "myapp_all.newsextended", + "fields": { + "newsbox_published": true, + "newsbox_changed_date": "2014-03-29T14:22:25.617Z", + "newsbox_creation_date": "2014-03-29T14:22:25.055Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2020-01-01T08:00:00Z", + "general_field": "Test", + "newsbox_indexed": true, + "newsbox_body": 21, + "newsbox_publication_end_date": null + } +} +] diff --git a/tests/myapp_all/models.py b/tests/myapp_all/models.py new file mode 100644 index 0000000000000000000000000000000000000000..dc25caa264c0e8a3e8df6261444dc59a435160cb --- /dev/null +++ b/tests/myapp_all/models.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models +from newsbox.models import NewsboxBase, NewsboxSEOBase, NewsboxExpiredBase +from newsbox_cms.models import NewsboxCMSBase, NewsboxPluginBase +from newsbox_hvad.models import NewsboxHVADBase + +class News(NewsboxHVADBase, NewsboxBase, NewsboxCMSBase): + class Meta: + verbose_name = 'news - HVADCMS' + verbose_name_plural = 'news - HVADCMS' + newsbox_detail_url_name = 'news_detail' + +class NewsComplete(NewsboxHVADBase, NewsboxBase, NewsboxCMSBase, NewsboxSEOBase, NewsboxExpiredBase): + class Meta: + verbose_name = 'news - CompleteHVADCMS' + verbose_name_plural = 'news - CompleteHVADCMS' + newsbox_detail_url_name = 'newscomplete_detail' + +class NewsExtended(NewsboxHVADBase, NewsboxBase, NewsboxCMSBase, NewsboxSEOBase, NewsboxExpiredBase): + general_field = models.CharField(max_length=50) + content_field = models.CharField(max_length=50) + seo_field = models.CharField(max_length=50) + + class Meta: + verbose_name = 'news - ExtendedHVADCMS' + verbose_name_plural = 'news - ExtendedHVADCMS' + newsbox_trans_fieldnames = ['content_field', 'seo_field'] + newsbox_detail_url_name = 'newsextended_detail' + + + +class NewsPlugin(NewsboxPluginBase): + newsbox_model = News + diff --git a/tests/myapp_all/templates/base.html b/tests/myapp_all/templates/base.html new file mode 100644 index 0000000000000000000000000000000000000000..914218d4ab6cf3f8b0e573e7cf62ea7bb0a026e7 --- /dev/null +++ b/tests/myapp_all/templates/base.html @@ -0,0 +1,13 @@ +{% load cms_tags sekizai_tags %} +<html> + <head> + {% render_block "css" %} + </head> + <body> + {% cms_toolbar %} + <div style="margin-top:200px;"> + {% block main %}{% endblock %} + </div> + {% render_block "js" %} + </body> +</html> diff --git a/tests/myapp_all/templates/list-cms.html b/tests/myapp_all/templates/list-cms.html new file mode 100644 index 0000000000000000000000000000000000000000..726433cc7586ae1049bc637168ac31d8251a52d8 --- /dev/null +++ b/tests/myapp_all/templates/list-cms.html @@ -0,0 +1 @@ +{% extends "newsbox/list-cms.html" %} diff --git a/tests/myapp_all/templates/page.html b/tests/myapp_all/templates/page.html new file mode 100644 index 0000000000000000000000000000000000000000..4ed33cab160a992834bd4306fefbed218e42d3aa --- /dev/null +++ b/tests/myapp_all/templates/page.html @@ -0,0 +1,6 @@ +{% extends "base.html" %} +{% load cms_tags %} + +{% block main %} + {% placeholder main %} +{% endblock %} diff --git a/tests/myapp_all/tests.py b/tests/myapp_all/tests.py new file mode 100644 index 0000000000000000000000000000000000000000..06a2feb2186509f35532709c69d715ed263c1e8a --- /dev/null +++ b/tests/myapp_all/tests.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from copy import copy + +from django.test import TestCase, Client +from django.contrib.auth.models import User +from django.core.paginator import EmptyPage +from django.utils.translation import activate +from cms.test_utils.testcases import CMSTestCase +from cms.plugin_rendering import render_plugin +from cms.api import create_page, add_plugin, publish_page, create_title +from djangocms_text_ckeditor.fields import HTMLField + +from .models import News, NewsComplete, NewsExtended, NewsPlugin as NewsPluginModel +from .cms_plugins import NewsPlugin + + +class NewsboxAbstractModelsTests(TestCase): + + fixtures = ['tests_data.json',] + + + def test_01_manager_published(self): + """ + Test if we only get really published news via the manager + """ + newsClasses = [ + News, NewsComplete, NewsExtended, + ] + for cls in newsClasses: + returned_ids = list(cls.objects.published().values_list( + 'id', flat=True).order_by('id')) + self.assertEqual( + (cls.__name__,returned_ids), + (cls.__name__,[1, 4, 6, 7,])) + + def test_02_summary_as_html_field(self): + """ + Test if newsbox_summary field is HTMLField + """ + newsClasses = [ + News, NewsComplete, NewsExtended, + ] + + for cls in newsClasses: + try: + transmodel = cls.translations.related.model + summary_field = transmodel._meta.get_field('newsbox_summary') + except: + self.fail('%s is not properly configured' % cls) + self.assertIsInstance(summary_field,HTMLField) + + +class NewsboxPageIntegrationTests(CMSTestCase): + + fixtures = ['tests_data.json',] + + def setUp(self): + self.super_user = User(username="test", is_staff=True, is_active=True, is_superuser=True) + self.super_user.set_password("test") + self.super_user.save() + + home = create_page(title='Home', slug='home', + template='page.html', + language='en', published=True, + reverse_id='home', in_navigation=True) + + create_title('fr', 'Accueil', home, slug='accueil') + home.publish('en') + home.publish('fr') + + self.page = create_page(title='News page', slug='news-page', + template='page.html', parent=home, + language='en', published=True, apphook='NewsApphook', + reverse_id='newspage', in_navigation=True) + create_title('fr', 'page Actualités', self.page, slug='page-actualites') + self.placeholder = self.page.placeholders.get(slot='main') + + self.plugin_en = add_plugin( + self.placeholder, 'NewsPlugin', 'en', + title = 'News', + numitems = 1, + with_pager = True, + page_link = None,) + self.plugin_en.save() + + self.plugin_fr = add_plugin( + self.placeholder, 'NewsPlugin', 'fr', + title = 'Actualités', + numitems = 1, + with_pager = True, + page_link = None,) + self.plugin_fr.save() + + self.page.publish('en') + self.page.publish('fr') + self.page.reload() + + self.newsPlugin = NewsPlugin() + self.placeholder = self.page.placeholders.get(slot='main') + + def test_01_cmsplugin_context(self): + expected_results = {'en':'News 7', 'fr':'Actualité 7',} + for lang in expected_results: + activate(lang) + context = self.get_context( + self.page.get_absolute_url(), page=self.page) + self.newsPlugin.render( + context, + getattr(self, 'plugin_%s' % lang), + self.placeholder) + self.assertIn('newsset', context) + self.assertEqual(context['newsset'][0].pk, 7) + self.assertEqual( + context['newsset'][0].newsbox_title, + expected_results[lang]) + self.assertEqual(context['newsset'].number, 1) + self.assertEqual(context['newsset'].paginator.num_pages, 4) + self.assertFalse(context['newsset'].has_previous()) + self.assertTrue(context['newsset'].has_next()) + self.assertRaises(EmptyPage, context['newsset'].previous_page_number) + self.assertEqual(context['newsset'].next_page_number(), 2) + + def test_02_wrong_language_404(self): + c = Client() + r_en = c.get('/en/news-page/2020/01/01/news-7/') + r_fr = c.get('/fr/page-actualites/2020/01/01/actualite-7/') + r_en_and_fr = c.get('/en/news-page/2020/01/01/actualite-7/') + self.assertEqual(r_en.status_code, 200) + self.assertEqual(r_fr.status_code, 200) + self.assertEqual(r_en_and_fr.status_code, 404) + + def test_03_get_absolute_url(self): + news7 = News.objects.get(pk=7) + expected_results = { + 'en':'/en/news-page/2020/01/01/news-7/', + 'fr':'/fr/page-actualites/2020/01/01/actualite-7/',} + for lang in expected_results: + activate(lang) + self.assertEqual(news7.get_absolute_url(), expected_results[lang]) diff --git a/tests/myapp_all/urls.py b/tests/myapp_all/urls.py new file mode 100644 index 0000000000000000000000000000000000000000..1753ed9add8c09cd5088913304aa86d19782c7e1 --- /dev/null +++ b/tests/myapp_all/urls.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.conf.urls import url, include +from django.conf.urls.i18n import i18n_patterns +from django.contrib import admin +from django.conf import settings + +admin.autodiscover() + +urlpatterns = i18n_patterns('', + url(r'^admin/', include(admin.site.urls)), + url(r'', include('cms.urls')), +) diff --git a/tests/myapp_all/urls_news.py b/tests/myapp_all/urls_news.py new file mode 100644 index 0000000000000000000000000000000000000000..9cdc95282bb8059d016a0ef7276db3d3c89045a0 --- /dev/null +++ b/tests/myapp_all/urls_news.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals + +from django.conf.urls import patterns, url +from newsbox_hvad.views import NewsboxHVADDetailView + +from .models import News + +urlpatterns = patterns( + '', + url( + r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/(?P<slug>[0-9a-zA-Z_-]+)/$', + NewsboxHVADDetailView.as_view(model=News,), + name='news_detail'), +) diff --git a/tests/myapp_cms/__init__.py b/tests/myapp_cms/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..40a96afc6ff09d58a702b76e3f7dd412fe975e26 --- /dev/null +++ b/tests/myapp_cms/__init__.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*- diff --git a/tests/myapp_cms/admin.py b/tests/myapp_cms/admin.py new file mode 100644 index 0000000000000000000000000000000000000000..05fbf1c16cac538b1597b68d97ddd6d45e4d75e1 --- /dev/null +++ b/tests/myapp_cms/admin.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.contrib import admin +from newsbox_cms.admin import NewsboxCMSAdmin +from newsbox.admin import NewsboxSEOAdmin, NewsboxExpiredAdmin + +from .models import News, NewsComplete, NewsExtended + +class NewsAdmin(NewsboxCMSAdmin): + pass + +admin.site.register(News, NewsAdmin) + + +class NewsCompleteAdmin(NewsboxCMSAdmin, NewsboxSEOAdmin, NewsboxExpiredAdmin): + pass + +admin.site.register(NewsComplete, NewsCompleteAdmin) + + +class NewsExtendedAdmin(NewsboxCMSAdmin, NewsboxSEOAdmin, NewsboxExpiredAdmin): + def get_fieldsets(self, request, obj=None): + fieldsets = super(NewsExtendedAdmin, self).get_fieldsets(request, obj) + fieldsets[0][1]['fields'].append('general_field') + fieldsets[2][1]['fields'].append('content_field') + fieldsets[3][1]['fields'].append('seo_field') + return fieldsets + + def get_list_display(self, request): + list_display = super(NewsExtendedAdmin, self).get_list_display(request) + list_display.append('seo_field') + return list_display + +admin.site.register(NewsExtended, NewsExtendedAdmin) diff --git a/tests/myapp_cms/cms_app.py b/tests/myapp_cms/cms_app.py new file mode 100644 index 0000000000000000000000000000000000000000..3e60259150f57a8d10090282a4c3a02b43c611c7 --- /dev/null +++ b/tests/myapp_cms/cms_app.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from cms.app_base import CMSApp +from cms.apphook_pool import apphook_pool + +class NewsApphook(CMSApp): + name = 'News' + urls = ["myapp_cms.urls_news"] + +apphook_pool.register(NewsApphook) diff --git a/tests/myapp_cms/cms_plugins.py b/tests/myapp_cms/cms_plugins.py new file mode 100644 index 0000000000000000000000000000000000000000..35817176c442fbd12dbc5e2f4896877370dcdc69 --- /dev/null +++ b/tests/myapp_cms/cms_plugins.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from cms.plugin_pool import plugin_pool +from newsbox_cms.cms_plugins import NewsboxPluginBase + +from .models import NewsPlugin as NewsPluginModel + + +class NewsPlugin(NewsboxPluginBase): + model = NewsPluginModel + +plugin_pool.register_plugin(NewsPlugin) diff --git a/tests/myapp_cms/fixtures/tests_data.json b/tests/myapp_cms/fixtures/tests_data.json new file mode 100644 index 0000000000000000000000000000000000000000..ef097333ab094dd5c91c235d35110107f6be7407 --- /dev/null +++ b/tests/myapp_cms/fixtures/tests_data.json @@ -0,0 +1,394 @@ +[ +{ + "pk": 1, + "model": "myapp_cms.news", + "fields": { + "newsbox_published": true, + "newsbox_slug": "news-1", + "newsbox_creation_date": "2014-03-11T13:53:45.196Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_summary": "<p>Summary of the news 1</p>", + "newsbox_body": 16, + "newsbox_changed_date": "2014-03-11T13:53:45.196Z", + "newsbox_title": "News 1" + } +}, +{ + "pk": 2, + "model": "myapp_cms.news", + "fields": { + "newsbox_published": false, + "newsbox_slug": "news-2", + "newsbox_creation_date": "2014-03-11T13:53:45.799Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_summary": "<p>Summary of the news 2</p>", + "newsbox_body": 18, + "newsbox_changed_date": "2014-03-11T13:53:45.799Z", + "newsbox_title": "News 2" + } +}, +{ + "pk": 3, + "model": "myapp_cms.news", + "fields": { + "newsbox_published": true, + "newsbox_slug": "news-3", + "newsbox_creation_date": "2014-03-11T13:53:46.402Z", + "newsbox_publication_start_date": "2020-01-01T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_summary": "<p>Summary of the news 3</p>", + "newsbox_body": 20, + "newsbox_changed_date": "2014-03-11T13:53:46.402Z", + "newsbox_title": "News 3" + } +}, +{ + "pk": 4, + "model": "myapp_cms.news", + "fields": { + "newsbox_published": true, + "newsbox_slug": "news-4", + "newsbox_creation_date": "2014-03-11T13:53:47.013Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_summary": "<p>Summary of the news 4</p>", + "newsbox_body": 22, + "newsbox_changed_date": "2014-03-11T13:53:47.013Z", + "newsbox_title": "News 4" + } +}, +{ + "pk": 5, + "model": "myapp_cms.news", + "fields": { + "newsbox_published": false, + "newsbox_slug": "news-5", + "newsbox_creation_date": "2014-03-11T13:53:47.618Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_summary": "<p>Summary of the news 5</p>", + "newsbox_body": 24, + "newsbox_changed_date": "2014-03-11T13:53:47.618Z", + "newsbox_title": "News 5" + } +}, +{ + "pk": 6, + "model": "myapp_cms.news", + "fields": { + "newsbox_published": true, + "newsbox_slug": "news-6", + "newsbox_creation_date": "2014-03-11T13:53:48.237Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2005-07-15T08:00:00Z", + "newsbox_summary": "<p>Summary of the news 6</p>", + "newsbox_body": 26, + "newsbox_changed_date": "2014-03-11T13:53:48.237Z", + "newsbox_title": "News 6" + } +}, +{ + "pk": 7, + "model": "myapp_cms.news", + "fields": { + "newsbox_published": true, + "newsbox_slug": "news-7", + "newsbox_creation_date": "2014-03-11T13:53:48.840Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2020-01-01T08:00:00Z", + "newsbox_summary": "<p>Summary of the news 7</p>", + "newsbox_body": 28, + "newsbox_changed_date": "2014-03-11T13:53:48.840Z", + "newsbox_title": "News 7" + } +}, +{ + "pk": 1, + "model": "myapp_cms.newscomplete", + "fields": { + "newsbox_published": true, + "newsbox_meta_description": "Meta description of the news 1", + "newsbox_slug": "news-1", + "newsbox_changed_date": "2014-03-11T13:53:52.178Z", + "newsbox_creation_date": "2014-03-11T13:53:52.178Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-1", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_summary": "<p>Summary of the news 1</p>", + "newsbox_body": 30, + "newsbox_publication_end_date": null, + "newsbox_title": "News 1" + } +}, +{ + "pk": 2, + "model": "myapp_cms.newscomplete", + "fields": { + "newsbox_published": false, + "newsbox_meta_description": "Meta description of the news 2", + "newsbox_slug": "news-2", + "newsbox_changed_date": "2014-03-11T13:53:52.797Z", + "newsbox_creation_date": "2014-03-11T13:53:52.797Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-2", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_summary": "<p>Summary of the news 2</p>", + "newsbox_body": 32, + "newsbox_publication_end_date": null, + "newsbox_title": "News 2" + } +}, +{ + "pk": 3, + "model": "myapp_cms.newscomplete", + "fields": { + "newsbox_published": true, + "newsbox_meta_description": "Meta description of the news 3", + "newsbox_slug": "news-3", + "newsbox_changed_date": "2014-03-11T13:53:53.426Z", + "newsbox_creation_date": "2014-03-11T13:53:53.426Z", + "newsbox_publication_start_date": "2020-01-01T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-3", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_summary": "<p>Summary of the news 3</p>", + "newsbox_body": 34, + "newsbox_publication_end_date": null, + "newsbox_title": "News 3" + } +}, +{ + "pk": 4, + "model": "myapp_cms.newscomplete", + "fields": { + "newsbox_published": true, + "newsbox_meta_description": "Meta description of the news 4", + "newsbox_slug": "news-4", + "newsbox_changed_date": "2014-03-11T13:53:54.055Z", + "newsbox_creation_date": "2014-03-11T13:53:54.055Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-4", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_summary": "<p>Summary of the news 4</p>", + "newsbox_body": 36, + "newsbox_publication_end_date": null, + "newsbox_title": "News 4" + } +}, +{ + "pk": 5, + "model": "myapp_cms.newscomplete", + "fields": { + "newsbox_published": false, + "newsbox_meta_description": "Meta description of the news 5", + "newsbox_slug": "news-5", + "newsbox_changed_date": "2014-03-11T13:53:54.674Z", + "newsbox_creation_date": "2014-03-11T13:53:54.674Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-5", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_summary": "<p>Summary of the news 5</p>", + "newsbox_body": 38, + "newsbox_publication_end_date": "2000-01-01T08:00:00Z", + "newsbox_title": "News 5" + } +}, +{ + "pk": 6, + "model": "myapp_cms.newscomplete", + "fields": { + "newsbox_published": true, + "newsbox_meta_description": "Meta description of the news 6", + "newsbox_slug": "news-6", + "newsbox_changed_date": "2014-03-11T13:53:55.303Z", + "newsbox_creation_date": "2014-03-11T13:53:55.303Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-6", + "newsbox_date": "2005-07-15T08:00:00Z", + "newsbox_indexed": false, + "newsbox_summary": "<p>Summary of the news 6</p>", + "newsbox_body": 40, + "newsbox_publication_end_date": null, + "newsbox_title": "News 6" + } +}, +{ + "pk": 7, + "model": "myapp_cms.newscomplete", + "fields": { + "newsbox_published": true, + "newsbox_meta_description": "Meta description of the news 7", + "newsbox_slug": "news-7", + "newsbox_changed_date": "2014-03-11T13:53:55.922Z", + "newsbox_creation_date": "2014-03-11T13:53:55.921Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-7", + "newsbox_date": "2020-01-01T08:00:00Z", + "newsbox_indexed": true, + "newsbox_summary": "<p>Summary of the news 7</p>", + "newsbox_body": 42, + "newsbox_publication_end_date": null, + "newsbox_title": "News 7" + } +}, +{ + "pk": 1, + "model": "myapp_cms.newsextended", + "fields": { + "newsbox_published": true, + "content_field": "", + "newsbox_slug": "news-1", + "newsbox_changed_date": "2014-03-11T13:53:40.980Z", + "newsbox_creation_date": "2014-03-11T13:53:40.980Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-1", + "newsbox_date": "2014-02-22T08:00:00Z", + "general_field": "", + "newsbox_indexed": true, + "seo_field": "", + "newsbox_summary": "<p>Summary of the news 1</p>", + "newsbox_meta_description": "Meta description of the news 1", + "newsbox_body": 2, + "newsbox_publication_end_date": null, + "newsbox_title": "News 1" + } +}, +{ + "pk": 2, + "model": "myapp_cms.newsextended", + "fields": { + "newsbox_published": false, + "content_field": "", + "newsbox_slug": "news-2", + "newsbox_changed_date": "2014-03-11T13:53:41.585Z", + "newsbox_creation_date": "2014-03-11T13:53:41.585Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-2", + "newsbox_date": "2014-02-22T08:00:00Z", + "general_field": "", + "newsbox_indexed": true, + "seo_field": "", + "newsbox_summary": "<p>Summary of the news 2</p>", + "newsbox_meta_description": "Meta description of the news 2", + "newsbox_body": 4, + "newsbox_publication_end_date": null, + "newsbox_title": "News 2" + } +}, +{ + "pk": 3, + "model": "myapp_cms.newsextended", + "fields": { + "newsbox_published": true, + "content_field": "", + "newsbox_slug": "news-3", + "newsbox_changed_date": "2014-03-11T13:53:42.180Z", + "newsbox_creation_date": "2014-03-11T13:53:42.180Z", + "newsbox_publication_start_date": "2020-01-01T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-3", + "newsbox_date": "2014-02-22T08:00:00Z", + "general_field": "", + "newsbox_indexed": true, + "seo_field": "", + "newsbox_summary": "<p>Summary of the news 3</p>", + "newsbox_meta_description": "Meta description of the news 3", + "newsbox_body": 6, + "newsbox_publication_end_date": null, + "newsbox_title": "News 3" + } +}, +{ + "pk": 4, + "model": "myapp_cms.newsextended", + "fields": { + "newsbox_published": true, + "content_field": "", + "newsbox_slug": "news-4", + "newsbox_changed_date": "2014-03-11T13:53:42.785Z", + "newsbox_creation_date": "2014-03-11T13:53:42.784Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-4", + "newsbox_date": "2014-02-22T08:00:00Z", + "general_field": "", + "newsbox_indexed": true, + "seo_field": "", + "newsbox_summary": "<p>Summary of the news 4</p>", + "newsbox_meta_description": "Meta description of the news 4", + "newsbox_body": 8, + "newsbox_publication_end_date": null, + "newsbox_title": "News 4" + } +}, +{ + "pk": 5, + "model": "myapp_cms.newsextended", + "fields": { + "newsbox_published": false, + "content_field": "", + "newsbox_slug": "news-5", + "newsbox_changed_date": "2014-03-11T13:53:43.377Z", + "newsbox_creation_date": "2014-03-11T13:53:43.377Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-5", + "newsbox_date": "2014-02-22T08:00:00Z", + "general_field": "", + "newsbox_indexed": true, + "seo_field": "", + "newsbox_summary": "<p>Summary of the news 5</p>", + "newsbox_meta_description": "Meta description of the news 5", + "newsbox_body": 10, + "newsbox_publication_end_date": "2000-01-01T08:00:00Z", + "newsbox_title": "News 5" + } +}, +{ + "pk": 6, + "model": "myapp_cms.newsextended", + "fields": { + "newsbox_published": true, + "content_field": "", + "newsbox_slug": "news-6", + "newsbox_changed_date": "2014-03-11T13:53:43.980Z", + "newsbox_creation_date": "2014-03-11T13:53:43.980Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-6", + "newsbox_date": "2005-07-15T08:00:00Z", + "general_field": "", + "newsbox_indexed": false, + "seo_field": "", + "newsbox_summary": "<p>Summary of the news 6</p>", + "newsbox_meta_description": "Meta description of the news 6", + "newsbox_body": 12, + "newsbox_publication_end_date": null, + "newsbox_title": "News 6" + } +}, +{ + "pk": 7, + "model": "myapp_cms.newsextended", + "fields": { + "newsbox_published": true, + "content_field": "", + "newsbox_slug": "news-7", + "newsbox_changed_date": "2014-03-11T13:53:44.583Z", + "newsbox_creation_date": "2014-03-11T13:53:44.583Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_meta_keywords": "keyword1, keyword2, news-7", + "newsbox_date": "2020-01-01T08:00:00Z", + "general_field": "", + "newsbox_indexed": true, + "seo_field": "", + "newsbox_summary": "<p>Summary of the news 7</p>", + "newsbox_meta_description": "Meta description of the news 7", + "newsbox_body": 14, + "newsbox_publication_end_date": null, + "newsbox_title": "News 7" + } +} +] diff --git a/tests/myapp_cms/models.py b/tests/myapp_cms/models.py new file mode 100644 index 0000000000000000000000000000000000000000..16622b3be7067855272dbbc6f64e19a27bbf47d9 --- /dev/null +++ b/tests/myapp_cms/models.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models +from newsbox.models import NewsboxBase, NewsboxSEOBase, NewsboxExpiredBase +from newsbox_cms.models import NewsboxCMSBase, NewsboxPluginBase + +class News(NewsboxBase, NewsboxCMSBase): + class Meta: + verbose_name = 'news - CMS' + verbose_name_plural = 'news - CMS' + newsbox_detail_url_name = 'news_detail' + + +class NewsComplete(NewsboxBase, NewsboxSEOBase, NewsboxExpiredBase, NewsboxCMSBase): + class Meta: + verbose_name = 'news - CompleteCMS' + verbose_name_plural = 'news - CompleteCMS' + newsbox_detail_url_name = 'newscomplete_detail' + + +class NewsExtended(NewsboxBase, NewsboxSEOBase, NewsboxExpiredBase, NewsboxCMSBase): + general_field = models.CharField(max_length=50) + content_field = models.CharField(max_length=50) + seo_field = models.CharField(max_length=50) + + class Meta: + verbose_name = 'news - ExtendedCMS' + verbose_name_plural = 'news - ExtendedCMS' + newsbox_detail_url_name = 'newsextended_detail' + + +class NewsPlugin(NewsboxPluginBase): + newsbox_model = News + diff --git a/tests/myapp_cms/templates/base.html b/tests/myapp_cms/templates/base.html new file mode 100644 index 0000000000000000000000000000000000000000..8e730c87d61dd1403be1be462f71167d8ae314cb --- /dev/null +++ b/tests/myapp_cms/templates/base.html @@ -0,0 +1,13 @@ +{% load cms_tags sekizai_tags %} +<html> + <head> + {% render_block "css" %} + </head> + <body> + {% cms_toolbar %} + {% block main %} + {% placeholder main %} + {% endblock %} + {% render_block "js" %} + </body> +</html> diff --git a/tests/myapp_cms/templates/list-cms.html b/tests/myapp_cms/templates/list-cms.html new file mode 100644 index 0000000000000000000000000000000000000000..726433cc7586ae1049bc637168ac31d8251a52d8 --- /dev/null +++ b/tests/myapp_cms/templates/list-cms.html @@ -0,0 +1 @@ +{% extends "newsbox/list-cms.html" %} diff --git a/tests/myapp_cms/templates/page.html b/tests/myapp_cms/templates/page.html new file mode 100644 index 0000000000000000000000000000000000000000..4ed33cab160a992834bd4306fefbed218e42d3aa --- /dev/null +++ b/tests/myapp_cms/templates/page.html @@ -0,0 +1,6 @@ +{% extends "base.html" %} +{% load cms_tags %} + +{% block main %} + {% placeholder main %} +{% endblock %} diff --git a/tests/myapp_cms/tests.py b/tests/myapp_cms/tests.py new file mode 100644 index 0000000000000000000000000000000000000000..f0a52845b2ea6df49e632a0824f25ef8e8070e36 --- /dev/null +++ b/tests/myapp_cms/tests.py @@ -0,0 +1,150 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from copy import copy + +from django.test import TestCase, Client +from django.contrib.auth.models import User +from django.core.paginator import EmptyPage +from cms.test_utils.testcases import CMSTestCase +from cms.plugin_rendering import render_plugin +from cms.api import create_page, add_plugin, publish_page +from djangocms_text_ckeditor.fields import HTMLField + +from .models import News, NewsComplete, NewsExtended, NewsPlugin as NewsPluginModel +from .cms_plugins import NewsPlugin + + +class NewsboxAbstractModelsTests(TestCase): + + fixtures = ['tests_data.json',] + + + def test_01_manager_published(self): + """ + Test if we only get really published news via the manager + """ + newsClasses = [ + News, NewsComplete, NewsExtended, + ] + for cls in newsClasses: + returned_ids = list(cls.objects.published().values_list( + 'id', flat=True).order_by('id')) + self.assertEqual( + (cls.__name__,returned_ids), + (cls.__name__,[1, 4, 6, 7,])) + + def test_02_summary_as_html_field(self): + """ + Test if newsbox_summary field is HTMLField + """ + newsClasses = [ + News, NewsComplete, NewsExtended, + ] + + for cls in newsClasses: + try: + summary_field = cls._meta.get_field('newsbox_summary') + except: + self.fail('%s is not properly configured' % cls) + self.assertIsInstance(summary_field, HTMLField) + + +class NewsboxPageIntegrationTests(CMSTestCase): + + fixtures = ['tests_data.json',] + + def setUp(self): + self.super_user = User(username="test", is_staff=True, is_active=True, is_superuser=True) + self.super_user.set_password("test") + self.super_user.save() + + home = create_page(title='Home', + template='page.html', + language='en', published=True, + reverse_id='home', in_navigation=True) + + self.page = create_page(title='News page', + template='page.html', parent=home, + language='en', published=True, apphook='NewsApphook', + reverse_id='newspage', in_navigation=True) + + self.placeholder = self.page.placeholders.get(slot='main') + self.plugin = add_plugin( + self.placeholder, 'NewsPlugin', 'en', + title = 'News', + numitems = 1, + with_pager = True, + page_link = None,) + self.plugin.save() + self.newsPlugin = NewsPlugin() + self.page = publish_page(self.page, self.super_user, 'en') + self.placeholder = self.page.placeholders.get(slot='main') + + def test_01_cmsplugin_context(self): + context = self.get_context(self.page.get_absolute_url(), page=self.page) + self.newsPlugin.render(context, self.plugin, self.placeholder) + self.assertIn('newsset', context) + self.assertEqual(context['newsset'][0].pk, 7) + self.assertEqual(context['newsset'].number, 1) + self.assertEqual(context['newsset'].paginator.num_pages, 4) + self.assertFalse(context['newsset'].has_previous()) + self.assertTrue(context['newsset'].has_next()) + self.assertRaises(EmptyPage, context['newsset'].previous_page_number) + self.assertEqual(context['newsset'].next_page_number(), 2) + + def test_02_cmsplugin_disable_pager(self): + context = self.get_context(self.page.get_absolute_url(), page=self.page) + plugin = copy(self.plugin) + plugin.with_pager = False + self.newsPlugin.render(context, plugin, self.placeholder) + self.assertIn('newsset', context) + with self.assertRaises(AttributeError): + getattr(context['newsset'], 'has_previous') + with self.assertRaises(AttributeError): + getattr(context['newsset'], 'paginator') + + def test_03_cmsplugin_numitems(self): + context = self.get_context(self.page.get_absolute_url(), page=self.page) + plugin = copy(self.plugin) + plugin.numitems = 2 + self.newsPlugin.render(context, plugin, self.placeholder) + self.assertIn('newsset', context) + self.assertEqual(context['newsset'].paginator.num_pages, 2) + + def test_04_cmsplugin_html(self): + context = self.get_context(self.page.get_absolute_url(), page=self.page) + self.newsPlugin.render(context, self.plugin, self.placeholder) + html = render_plugin( + context, + self.newsPlugin, + self.placeholder, + self.newsPlugin.render_template) + self.assertIn('<a href="/news-page/2020/01/01/news-7/">News 7</a>', html) + self.assertIn('<a class="next" href="?page=2">Next news</a>', html) + + def test_05_app_view_detail_200(self): + """ + Test if generic day views return right informations. + """ + c = Client() + r = c.get('/news-page/2005/07/15/news-6/') + self.assertEqual(r.status_code, 200) + self.assertEqual(r.context['news'].pk, 6) + + def test_06_app_view_detail_404(self): + """ + Test if generic day views return a 404 with an URL with a date without + any news. + """ + c = Client() + r = c.get('/news-page/1985/07/02/my-birthday/') + self.assertEqual(r.status_code, 404) + + def test_07_app_view_detail_404_not_published(self): + """ + Test if generic day views return a 404 with an URL with a not published + news + """ + c = Client() + r = c.get('/news-page/2014/02/22/news-2/') + self.assertEqual(r.status_code, 404) diff --git a/tests/myapp_cms/urls.py b/tests/myapp_cms/urls.py new file mode 100644 index 0000000000000000000000000000000000000000..2a7ddb5aa121a3fc2cbe246b7c05f4278931a0f0 --- /dev/null +++ b/tests/myapp_cms/urls.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.conf.urls import url, include, patterns +from django.contrib import admin +from django.conf import settings + +admin.autodiscover() + +urlpatterns = patterns('', + url(r'^admin/', include(admin.site.urls)), + url(r'', include('cms.urls')), +) diff --git a/tests/myapp_cms/urls_news.py b/tests/myapp_cms/urls_news.py new file mode 100644 index 0000000000000000000000000000000000000000..a9a706d718a2bf8c43e31e2352995c8b550910f3 --- /dev/null +++ b/tests/myapp_cms/urls_news.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.conf.urls import patterns, url +from newsbox.views import NewsboxDetailView + +from .models import News + +urlpatterns = patterns( + '', + url( + r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/(?P<slug>[0-9a-zA-Z_-]+)/$', + NewsboxDetailView.as_view( + model=News,), + name='news_detail'), +) diff --git a/tests/myapp_hvad/__init__.py b/tests/myapp_hvad/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..40a96afc6ff09d58a702b76e3f7dd412fe975e26 --- /dev/null +++ b/tests/myapp_hvad/__init__.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*- diff --git a/tests/myapp_hvad/fixtures/tests_data.json b/tests/myapp_hvad/fixtures/tests_data.json new file mode 100644 index 0000000000000000000000000000000000000000..1c6ef94c10adaaafba9b688206993ff258a7c6e1 --- /dev/null +++ b/tests/myapp_hvad/fixtures/tests_data.json @@ -0,0 +1,856 @@ +[ +{ + "pk": 1, + "model": "myapp_hvad.newstranslation", + "fields": { + "newsbox_slug": "news-1", + "master": 1, + "newsbox_summary": "Summary of the news 1", + "language_code": "en", + "newsbox_body": "Body of the news 1", + "newsbox_title": "News 1" + } +}, +{ + "pk": 2, + "model": "myapp_hvad.newstranslation", + "fields": { + "newsbox_slug": "actualite-1", + "master": 1, + "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 1", + "language_code": "fr", + "newsbox_body": "Corps de l'actualit\u00e9 1", + "newsbox_title": "Actualit\u00e9 1" + } +}, +{ + "pk": 3, + "model": "myapp_hvad.newstranslation", + "fields": { + "newsbox_slug": "news-2", + "master": 2, + "newsbox_summary": "Summary of the news 2", + "language_code": "en", + "newsbox_body": "Body of the news 2", + "newsbox_title": "News 2" + } +}, +{ + "pk": 4, + "model": "myapp_hvad.newstranslation", + "fields": { + "newsbox_slug": "actualite-2", + "master": 2, + "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 2", + "language_code": "fr", + "newsbox_body": "Corps de l'actualit\u00e9 2", + "newsbox_title": "Actualit\u00e9 2" + } +}, +{ + "pk": 5, + "model": "myapp_hvad.newstranslation", + "fields": { + "newsbox_slug": "news-3", + "master": 3, + "newsbox_summary": "Summary of the news 3", + "language_code": "en", + "newsbox_body": "Body of the news 3", + "newsbox_title": "News 3" + } +}, +{ + "pk": 6, + "model": "myapp_hvad.newstranslation", + "fields": { + "newsbox_slug": "actualite-3", + "master": 3, + "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 3", + "language_code": "fr", + "newsbox_body": "Corps de l'actualit\u00e9 3", + "newsbox_title": "Actualit\u00e9 3" + } +}, +{ + "pk": 7, + "model": "myapp_hvad.newstranslation", + "fields": { + "newsbox_slug": "news-4", + "master": 4, + "newsbox_summary": "Summary of the news 4", + "language_code": "en", + "newsbox_body": "", + "newsbox_title": "News 4" + } +}, +{ + "pk": 8, + "model": "myapp_hvad.newstranslation", + "fields": { + "newsbox_slug": "actualite-4", + "master": 4, + "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 4", + "language_code": "fr", + "newsbox_body": "Corps de l'actualit\u00e9 4", + "newsbox_title": "Actualit\u00e9 4" + } +}, +{ + "pk": 9, + "model": "myapp_hvad.newstranslation", + "fields": { + "newsbox_slug": "news-5", + "master": 5, + "newsbox_summary": "Summary of the news 5", + "language_code": "en", + "newsbox_body": "Body of the news 5", + "newsbox_title": "News 5" + } +}, +{ + "pk": 10, + "model": "myapp_hvad.newstranslation", + "fields": { + "newsbox_slug": "actualite-5", + "master": 5, + "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 5", + "language_code": "fr", + "newsbox_body": "Corps de l'actualit\u00e9 5", + "newsbox_title": "Actualit\u00e9 5" + } +}, +{ + "pk": 11, + "model": "myapp_hvad.newstranslation", + "fields": { + "newsbox_slug": "news-6", + "master": 6, + "newsbox_summary": "Summary of the news 6", + "language_code": "en", + "newsbox_body": "Body of the news 6", + "newsbox_title": "News 6" + } +}, +{ + "pk": 12, + "model": "myapp_hvad.newstranslation", + "fields": { + "newsbox_slug": "actualite-6", + "master": 6, + "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 6", + "language_code": "fr", + "newsbox_body": "Corps de l'actualit\u00e9 6", + "newsbox_title": "Actualit\u00e9 6" + } +}, +{ + "pk": 13, + "model": "myapp_hvad.newstranslation", + "fields": { + "newsbox_slug": "news-7", + "master": 7, + "newsbox_summary": "Summary of the news 7", + "language_code": "en", + "newsbox_body": "Body of the news 7", + "newsbox_title": "News 7" + } +}, +{ + "pk": 14, + "model": "myapp_hvad.newstranslation", + "fields": { + "newsbox_slug": "actualite-7", + "master": 7, + "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 7", + "language_code": "fr", + "newsbox_body": "Corps de l'actualit\u00e9 7", + "newsbox_title": "Actualit\u00e9 7" + } +}, +{ + "pk": 1, + "model": "myapp_hvad.news", + "fields": { + "newsbox_creation_date": "2014-03-11T13:53:29.989Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_changed_date": "2014-03-11T13:53:30.366Z", + "newsbox_published": true, + "newsbox_date": "2014-02-22T08:00:00Z" + } +}, +{ + "pk": 2, + "model": "myapp_hvad.news", + "fields": { + "newsbox_creation_date": "2014-03-11T13:53:30.736Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_changed_date": "2014-03-11T13:53:31.111Z", + "newsbox_published": false, + "newsbox_date": "2014-02-22T08:00:00Z" + } +}, +{ + "pk": 3, + "model": "myapp_hvad.news", + "fields": { + "newsbox_creation_date": "2014-03-11T13:53:31.496Z", + "newsbox_publication_start_date": "2020-01-01T08:00:00Z", + "newsbox_changed_date": "2014-03-11T13:53:31.884Z", + "newsbox_published": true, + "newsbox_date": "2014-02-22T08:00:00Z" + } +}, +{ + "pk": 4, + "model": "myapp_hvad.news", + "fields": { + "newsbox_creation_date": "2014-03-11T13:53:32.261Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_changed_date": "2014-03-11T13:53:32.646Z", + "newsbox_published": true, + "newsbox_date": "2014-02-22T08:00:00Z" + } +}, +{ + "pk": 5, + "model": "myapp_hvad.news", + "fields": { + "newsbox_creation_date": "2014-03-11T13:53:33.016Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_changed_date": "2014-03-11T13:53:33.377Z", + "newsbox_published": false, + "newsbox_date": "2014-02-22T08:00:00Z" + } +}, +{ + "pk": 6, + "model": "myapp_hvad.news", + "fields": { + "newsbox_creation_date": "2014-03-11T13:53:33.752Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_changed_date": "2014-03-11T13:53:34.122Z", + "newsbox_published": true, + "newsbox_date": "2005-07-15T08:00:00Z" + } +}, +{ + "pk": 7, + "model": "myapp_hvad.news", + "fields": { + "newsbox_creation_date": "2014-03-11T13:53:34.499Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_changed_date": "2014-03-11T13:53:34.868Z", + "newsbox_published": true, + "newsbox_date": "2020-01-01T08:00:00Z" + } +}, +{ + "pk": 1, + "model": "myapp_hvad.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-1", + "newsbox_slug": "news-1", + "newsbox_meta_description": "Meta description of the news 1", + "master": 1, + "newsbox_summary": "Summary of the news 1", + "language_code": "en", + "newsbox_body": "Body of the news 1", + "newsbox_title": "News 1" + } +}, +{ + "pk": 2, + "model": "myapp_hvad.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-1", + "newsbox_slug": "actualite-1", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 1", + "master": 1, + "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 1", + "language_code": "fr", + "newsbox_body": "Corps de l'actualit\u00e9 1", + "newsbox_title": "Actualit\u00e9 1" + } +}, +{ + "pk": 3, + "model": "myapp_hvad.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-2", + "newsbox_slug": "news-2", + "newsbox_meta_description": "Meta description of the news 2", + "master": 2, + "newsbox_summary": "Summary of the news 2", + "language_code": "en", + "newsbox_body": "Body of the news 2", + "newsbox_title": "News 2" + } +}, +{ + "pk": 4, + "model": "myapp_hvad.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-2", + "newsbox_slug": "actualite-2", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 2", + "master": 2, + "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 2", + "language_code": "fr", + "newsbox_body": "Corps de l'actualit\u00e9 2", + "newsbox_title": "Actualit\u00e9 2" + } +}, +{ + "pk": 5, + "model": "myapp_hvad.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-3", + "newsbox_slug": "news-3", + "newsbox_meta_description": "Meta description of the news 3", + "master": 3, + "newsbox_summary": "Summary of the news 3", + "language_code": "en", + "newsbox_body": "Body of the news 3", + "newsbox_title": "News 3" + } +}, +{ + "pk": 6, + "model": "myapp_hvad.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-3", + "newsbox_slug": "actualite-3", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 3", + "master": 3, + "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 3", + "language_code": "fr", + "newsbox_body": "Corps de l'actualit\u00e9 3", + "newsbox_title": "Actualit\u00e9 3" + } +}, +{ + "pk": 7, + "model": "myapp_hvad.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-4", + "newsbox_slug": "news-4", + "newsbox_meta_description": "Meta description of the news 4", + "master": 4, + "newsbox_summary": "Summary of the news 4", + "language_code": "en", + "newsbox_body": "", + "newsbox_title": "News 4" + } +}, +{ + "pk": 8, + "model": "myapp_hvad.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-4", + "newsbox_slug": "actualite-4", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 4", + "master": 4, + "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 4", + "language_code": "fr", + "newsbox_body": "Corps de l'actualit\u00e9 4", + "newsbox_title": "Actualit\u00e9 4" + } +}, +{ + "pk": 9, + "model": "myapp_hvad.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-5", + "newsbox_slug": "news-5", + "newsbox_meta_description": "Meta description of the news 5", + "master": 5, + "newsbox_summary": "Summary of the news 5", + "language_code": "en", + "newsbox_body": "Body of the news 5", + "newsbox_title": "News 5" + } +}, +{ + "pk": 10, + "model": "myapp_hvad.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-5", + "newsbox_slug": "actualite-5", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 5", + "master": 5, + "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 5", + "language_code": "fr", + "newsbox_body": "Corps de l'actualit\u00e9 5", + "newsbox_title": "Actualit\u00e9 5" + } +}, +{ + "pk": 11, + "model": "myapp_hvad.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-6", + "newsbox_slug": "news-6", + "newsbox_meta_description": "Meta description of the news 6", + "master": 6, + "newsbox_summary": "Summary of the news 6", + "language_code": "en", + "newsbox_body": "Body of the news 6", + "newsbox_title": "News 6" + } +}, +{ + "pk": 12, + "model": "myapp_hvad.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-6", + "newsbox_slug": "actualite-6", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 6", + "master": 6, + "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 6", + "language_code": "fr", + "newsbox_body": "Corps de l'actualit\u00e9 6", + "newsbox_title": "Actualit\u00e9 6" + } +}, +{ + "pk": 13, + "model": "myapp_hvad.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-7", + "newsbox_slug": "news-7", + "newsbox_meta_description": "Meta description of the news 7", + "master": 7, + "newsbox_summary": "Summary of the news 7", + "language_code": "en", + "newsbox_body": "Body of the news 7", + "newsbox_title": "News 7" + } +}, +{ + "pk": 14, + "model": "myapp_hvad.newscompletetranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-7", + "newsbox_slug": "actualite-7", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 7", + "master": 7, + "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 7", + "language_code": "fr", + "newsbox_body": "Corps de l'actualit\u00e9 7", + "newsbox_title": "Actualit\u00e9 7" + } +}, +{ + "pk": 1, + "model": "myapp_hvad.newscomplete", + "fields": { + "newsbox_published": true, + "newsbox_changed_date": "2014-03-11T13:53:35.631Z", + "newsbox_creation_date": "2014-03-11T13:53:35.238Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 2, + "model": "myapp_hvad.newscomplete", + "fields": { + "newsbox_published": false, + "newsbox_changed_date": "2014-03-11T13:53:36.378Z", + "newsbox_creation_date": "2014-03-11T13:53:35.993Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 3, + "model": "myapp_hvad.newscomplete", + "fields": { + "newsbox_published": true, + "newsbox_changed_date": "2014-03-11T13:53:37.124Z", + "newsbox_creation_date": "2014-03-11T13:53:36.747Z", + "newsbox_publication_start_date": "2020-01-01T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 4, + "model": "myapp_hvad.newscomplete", + "fields": { + "newsbox_published": true, + "newsbox_changed_date": "2014-03-11T13:53:37.871Z", + "newsbox_creation_date": "2014-03-11T13:53:37.494Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 5, + "model": "myapp_hvad.newscomplete", + "fields": { + "newsbox_published": false, + "newsbox_changed_date": "2014-03-11T13:53:38.660Z", + "newsbox_creation_date": "2014-03-11T13:53:38.272Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "newsbox_indexed": true, + "newsbox_publication_end_date": "2000-01-01T08:00:00Z" + } +}, +{ + "pk": 6, + "model": "myapp_hvad.newscomplete", + "fields": { + "newsbox_published": true, + "newsbox_changed_date": "2014-03-11T13:53:39.438Z", + "newsbox_creation_date": "2014-03-11T13:53:39.045Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2005-07-15T08:00:00Z", + "newsbox_indexed": false, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 7, + "model": "myapp_hvad.newscomplete", + "fields": { + "newsbox_published": true, + "newsbox_changed_date": "2014-03-11T13:53:40.209Z", + "newsbox_creation_date": "2014-03-11T13:53:39.824Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2020-01-01T08:00:00Z", + "newsbox_indexed": true, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 1, + "model": "myapp_hvad.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-1", + "content_field": "Extra content of the news 1", + "newsbox_slug": "news-1", + "newsbox_meta_description": "Meta description of the news 1", + "seo_field": "Extra SEO of the news 1", + "master": 1, + "newsbox_summary": "Summary of the news 1", + "language_code": "en", + "newsbox_body": "Body of the news 1", + "newsbox_title": "News 1" + } +}, +{ + "pk": 2, + "model": "myapp_hvad.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-1", + "content_field": "Contenu additionnel de l'actualit\u00e9 1", + "newsbox_slug": "actualite-1", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 1", + "seo_field": "SEO additionnel de l'actualit\u00e9 1", + "master": 1, + "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 1", + "language_code": "fr", + "newsbox_body": "Corps de l'actualit\u00e9 1", + "newsbox_title": "Actualit\u00e9 1" + } +}, +{ + "pk": 3, + "model": "myapp_hvad.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-2", + "content_field": "Extra content of the news 2", + "newsbox_slug": "news-2", + "newsbox_meta_description": "Meta description of the news 2", + "seo_field": "Extra SEO of the news 2", + "master": 2, + "newsbox_summary": "Summary of the news 2", + "language_code": "en", + "newsbox_body": "Body of the news 2", + "newsbox_title": "News 2" + } +}, +{ + "pk": 4, + "model": "myapp_hvad.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-2", + "content_field": "Contenu additionnel de l'actualit\u00e9 2", + "newsbox_slug": "actualite-2", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 2", + "seo_field": "SEO additionnel de l'actualit\u00e9 2", + "master": 2, + "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 2", + "language_code": "fr", + "newsbox_body": "Corps de l'actualit\u00e9 2", + "newsbox_title": "Actualit\u00e9 2" + } +}, +{ + "pk": 5, + "model": "myapp_hvad.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-3", + "content_field": "Extra content of the news 3", + "newsbox_slug": "news-3", + "newsbox_meta_description": "Meta description of the news 3", + "seo_field": "Extra SEO of the news 3", + "master": 3, + "newsbox_summary": "Summary of the news 3", + "language_code": "en", + "newsbox_body": "Body of the news 3", + "newsbox_title": "News 3" + } +}, +{ + "pk": 6, + "model": "myapp_hvad.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-3", + "content_field": "Contenu additionnel de l'actualit\u00e9 3", + "newsbox_slug": "actualite-3", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 3", + "seo_field": "SEO additionnel de l'actualit\u00e9 3", + "master": 3, + "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 3", + "language_code": "fr", + "newsbox_body": "Corps de l'actualit\u00e9 3", + "newsbox_title": "Actualit\u00e9 3" + } +}, +{ + "pk": 7, + "model": "myapp_hvad.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-4", + "content_field": "Extra content of the news 4", + "newsbox_slug": "news-4", + "newsbox_meta_description": "Meta description of the news 4", + "seo_field": "Extra SEO of the news 4", + "master": 4, + "newsbox_summary": "Summary of the news 4", + "language_code": "en", + "newsbox_body": "", + "newsbox_title": "News 4" + } +}, +{ + "pk": 8, + "model": "myapp_hvad.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-4", + "content_field": "Contenu additionnel de l'actualit\u00e9 4", + "newsbox_slug": "actualite-4", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 4", + "seo_field": "SEO additionnel de l'actualit\u00e9 4", + "master": 4, + "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 4", + "language_code": "fr", + "newsbox_body": "Corps de l'actualit\u00e9 4", + "newsbox_title": "Actualit\u00e9 4" + } +}, +{ + "pk": 9, + "model": "myapp_hvad.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-5", + "content_field": "Extra content of the news 5", + "newsbox_slug": "news-5", + "newsbox_meta_description": "Meta description of the news 5", + "seo_field": "Extra SEO of the news 5", + "master": 5, + "newsbox_summary": "Summary of the news 5", + "language_code": "en", + "newsbox_body": "Body of the news 5", + "newsbox_title": "News 5" + } +}, +{ + "pk": 10, + "model": "myapp_hvad.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-5", + "content_field": "Contenu additionnel de l'actualit\u00e9 5", + "newsbox_slug": "actualite-5", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 5", + "seo_field": "SEO additionnel de l'actualit\u00e9 5", + "master": 5, + "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 5", + "language_code": "fr", + "newsbox_body": "Corps de l'actualit\u00e9 5", + "newsbox_title": "Actualit\u00e9 5" + } +}, +{ + "pk": 11, + "model": "myapp_hvad.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-6", + "content_field": "Extra content of the news 6", + "newsbox_slug": "news-6", + "newsbox_meta_description": "Meta description of the news 6", + "seo_field": "Extra SEO of the news 6", + "master": 6, + "newsbox_summary": "Summary of the news 6", + "language_code": "en", + "newsbox_body": "Body of the news 6", + "newsbox_title": "News 6" + } +}, +{ + "pk": 12, + "model": "myapp_hvad.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-6", + "content_field": "Contenu additionnel de l'actualit\u00e9 6", + "newsbox_slug": "actualite-6", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 6", + "seo_field": "SEO additionnel de l'actualit\u00e9 6", + "master": 6, + "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 6", + "language_code": "fr", + "newsbox_body": "Corps de l'actualit\u00e9 6", + "newsbox_title": "Actualit\u00e9 6" + } +}, +{ + "pk": 13, + "model": "myapp_hvad.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "keyword1, keyword2, news-7", + "content_field": "Extra content of the news 7", + "newsbox_slug": "news-7", + "newsbox_meta_description": "Meta description of the news 7", + "seo_field": "Extra SEO of the news 7", + "master": 7, + "newsbox_summary": "Summary of the news 7", + "language_code": "en", + "newsbox_body": "Body of the news 7", + "newsbox_title": "News 7" + } +}, +{ + "pk": 14, + "model": "myapp_hvad.newsextendedtranslation", + "fields": { + "newsbox_meta_keywords": "motclef1, motclef2, actualite-7", + "content_field": "Contenu additionnel de l'actualit\u00e9 7", + "newsbox_slug": "actualite-7", + "newsbox_meta_description": "Meta description de l'actualit\u00e9 7", + "seo_field": "SEO additionnel de l'actualit\u00e9 7", + "master": 7, + "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 7", + "language_code": "fr", + "newsbox_body": "Corps de l'actualit\u00e9 7", + "newsbox_title": "Actualit\u00e9 7" + } +}, +{ + "pk": 1, + "model": "myapp_hvad.newsextended", + "fields": { + "newsbox_published": true, + "newsbox_changed_date": "2014-03-11T13:53:56.517Z", + "newsbox_creation_date": "2014-03-11T13:53:56.124Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "general_field": "Test", + "newsbox_indexed": true, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 2, + "model": "myapp_hvad.newsextended", + "fields": { + "newsbox_published": false, + "newsbox_changed_date": "2014-03-11T13:53:57.329Z", + "newsbox_creation_date": "2014-03-11T13:53:56.946Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "general_field": "Test", + "newsbox_indexed": true, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 3, + "model": "myapp_hvad.newsextended", + "fields": { + "newsbox_published": true, + "newsbox_changed_date": "2014-03-11T13:53:58.094Z", + "newsbox_creation_date": "2014-03-11T13:53:57.716Z", + "newsbox_publication_start_date": "2020-01-01T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "general_field": "Test", + "newsbox_indexed": true, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 4, + "model": "myapp_hvad.newsextended", + "fields": { + "newsbox_published": true, + "newsbox_changed_date": "2014-03-11T13:53:59.046Z", + "newsbox_creation_date": "2014-03-11T13:53:58.487Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "general_field": "Test", + "newsbox_indexed": true, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 5, + "model": "myapp_hvad.newsextended", + "fields": { + "newsbox_published": false, + "newsbox_changed_date": "2014-03-11T13:53:59.843Z", + "newsbox_creation_date": "2014-03-11T13:53:59.451Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2014-02-22T08:00:00Z", + "general_field": "Test", + "newsbox_indexed": true, + "newsbox_publication_end_date": "2000-01-01T08:00:00Z" + } +}, +{ + "pk": 6, + "model": "myapp_hvad.newsextended", + "fields": { + "newsbox_published": true, + "newsbox_changed_date": "2014-03-11T13:54:00.657Z", + "newsbox_creation_date": "2014-03-11T13:54:00.246Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2005-07-15T08:00:00Z", + "general_field": "Test", + "newsbox_indexed": false, + "newsbox_publication_end_date": null + } +}, +{ + "pk": 7, + "model": "myapp_hvad.newsextended", + "fields": { + "newsbox_published": true, + "newsbox_changed_date": "2014-03-11T13:54:01.420Z", + "newsbox_creation_date": "2014-03-11T13:54:01.033Z", + "newsbox_publication_start_date": "1985-07-02T08:00:00Z", + "newsbox_date": "2020-01-01T08:00:00Z", + "general_field": "Test", + "newsbox_indexed": true, + "newsbox_publication_end_date": null + } +} +] diff --git a/tests/myapp_hvad/models.py b/tests/myapp_hvad/models.py new file mode 100644 index 0000000000000000000000000000000000000000..84885858e14cc2afdb1d79707f1bcc2eff747353 --- /dev/null +++ b/tests/myapp_hvad/models.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models +from newsbox.models import NewsboxBase, NewsboxSEOBase, NewsboxExpiredBase +from newsbox_hvad.models import NewsboxHVADBase + +class News(NewsboxHVADBase, NewsboxBase): + class Meta: + verbose_name = 'news - HVAD' + verbose_name_plural = 'news - HVAD' + +class NewsComplete(NewsboxHVADBase, NewsboxBase, NewsboxSEOBase, NewsboxExpiredBase): + class Meta: + verbose_name = 'news - CompleteHVAD' + verbose_name_plural = 'news - CompleteHVAD' + +class NewsExtended(NewsboxHVADBase, NewsboxBase, NewsboxSEOBase, NewsboxExpiredBase): + general_field = models.CharField(max_length=50) + content_field = models.CharField(max_length=50) + seo_field = models.CharField(max_length=50) + + class Meta: + verbose_name = 'news - ExtendedHVAD' + verbose_name_plural = 'news - ExtendedHVAD' + newsbox_trans_fieldnames = ['content_field', 'seo_field'] + diff --git a/tests/myapp_hvad/tests.py b/tests/myapp_hvad/tests.py new file mode 100644 index 0000000000000000000000000000000000000000..60e3504cbfaf2899eb7b7bb0246a1de0ab10e9ac --- /dev/null +++ b/tests/myapp_hvad/tests.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.test import TestCase, Client +from django.core.paginator import EmptyPage +from django.utils.translation import activate + +from .models import News, NewsComplete, NewsExtended + + + + +class NewsboxAbstractModelsTests(TestCase): + + fixtures = ['tests_data.json',] + + def test_01_manager_published(self): + """ + Test if we only get really published news via the manager + """ + newsClasses = [ + News, NewsComplete, NewsExtended + ] + for cls in newsClasses: + returned_ids = list(cls.objects.published().values_list( + 'id', flat=True).order_by('id')) + self.assertEqual( + (cls.__name__,returned_ids), + (cls.__name__,[1, 4, 6, 7,])) + + def test_02_extra_translated_fields(self): + news = NewsExtended.objects.get(pk=1) + self.assertEqual( + list(news.get_available_languages()), + ['en', 'fr']) + news_fr = NewsExtended.objects.language('fr').get(pk=1) + news_en = NewsExtended.objects.language('en').get(pk=1) + self.assertEqual( + news_fr.content_field, + 'Contenu additionnel de l\'actualité 1') + self.assertEqual( + news_en.content_field, + 'Extra content of the news 1') + self.assertEqual(news_en.general_field, news_fr.general_field) + + def test_03_view_archive_200(self): + """ + Test if generic archive view return right informations. + """ + c = Client() + r = c.get('/en/news/') + + self.assertEqual(r.status_code, 200) + self.assertIn('newsset', r.context) + self.assertEqual(r.context['newsset'][0].pk, 7) + self.assertEqual(r.context['newsset'].number, 1) + self.assertEqual(r.context['newsset'].paginator.num_pages, 4) + self.assertFalse(r.context['newsset'].has_previous()) + self.assertTrue(r.context['newsset'].has_next()) + self.assertRaises(EmptyPage, r.context['newsset'].previous_page_number) + self.assertEqual(r.context['newsset'].next_page_number(), 2) + + + def test_04_view_detail_200(self): + """ + Test if generic day views return right informations. + """ + c = Client() + r = c.get('/en/newsbox/myapp_hvad/news/2005/07/15/news-6/') + self.assertEqual(r.status_code, 200) + self.assertEqual(r.context['news'].pk, 6) + + def test_05_view_detail_404(self): + """ + Test if generic day views return a 404 with an URL with a date without + any news. + """ + c = Client() + r = c.get('/en/newsbox/myapp_hvad/news/1985/07/02/my-birthday/') + self.assertEqual(r.status_code, 404) + + def test_06_view_detail_404_not_published(self): + """ + Test if generic day views return a 404 with an URL with a not published + news + """ + c = Client() + r = c.get('/en/newsbox/myapp_hvad/news/2014/02/22/news-2/') + self.assertEqual(r.status_code, 404) + + def test_07_view_detail_translated(self): + c = Client() + r_en = c.get('/en/newsbox/myapp_hvad/news/2005/07/15/news-6/') + r_fr = c.get('/fr/newsbox/myapp_hvad/news/2005/07/15/actualite-6/') + self.assertEqual(r_fr.context['news'].pk, r_en.context['news'].pk) + self.assertEqual(r_fr.context['news'].newsbox_title, 'Actualité 6') + self.assertEqual(r_en.context['news'].newsbox_title, 'News 6') + + def test_08_get_absolute_url(self): + news6 = News.objects.get(pk=6) + expected_results = { + 'en':'/en/newsbox/myapp_hvad/news/2005/07/15/news-6/', + 'fr':'/fr/newsbox/myapp_hvad/news/2005/07/15/actualite-6/',} + for lang in expected_results: + activate(lang) + self.assertEqual(news6.get_absolute_url(), expected_results[lang]) diff --git a/tests/myapp_hvad/urls.py b/tests/myapp_hvad/urls.py new file mode 100644 index 0000000000000000000000000000000000000000..04c49fa68a74c6908af7b07ef2c40dd4ac0f6894 --- /dev/null +++ b/tests/myapp_hvad/urls.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.conf.urls import url, include +from django.conf.urls.i18n import i18n_patterns +from django.contrib import admin +from django.conf import settings +from newsbox.views import NewsboxYearArchiveView, NewsboxArchiveView + +from .models import News + +admin.autodiscover() + +urlpatterns = i18n_patterns('', + url(r'^admin/', include(admin.site.urls)), + url(r'^', include('newsbox_hvad.urls')), + url(r'^news/$', + NewsboxArchiveView.as_view(model=News, paginate_by=1), + name='news_list',), + url(r'^news/(?P<year>\d{4})/$', + NewsboxYearArchiveView.as_view(model=News, paginate_by=1), + name='news_list_y',), +) diff --git a/tests/runtests.sh b/tests/runtests.sh new file mode 100755 index 0000000000000000000000000000000000000000..274086ae7f10564efcecf2f90dbbef012b8f75dd --- /dev/null +++ b/tests/runtests.sh @@ -0,0 +1,26 @@ +#!/bin/sh +export PYTHONPATH="./" + +if [ `which django-admin.py` ] ; then + export DJANGO_ADMIN=django-admin.py +else + export DJANGO_ADMIN=django-admin +fi + +export args="$@" +if [ -z "$args" ] ; then + # avoid running the tests for django.contrib.* (they're in INSTALLED_APPS) + export args=myapp +fi + +if [ "$args" = "myapp_cms" ] ; then + export DJANGO_SETTINGS_MODULE='settings_cms' +elif [ "$args" = "myapp_hvad" ] ; then + export DJANGO_SETTINGS_MODULE='settings_hvad' +elif [ "$args" = "myapp_all" ] ; then + export DJANGO_SETTINGS_MODULE='settings_all' +else + export DJANGO_SETTINGS_MODULE='settings' +fi + +$DJANGO_ADMIN test --traceback --settings=$DJANGO_SETTINGS_MODULE --verbosity 2 --pythonpath="../" "$args" diff --git a/tests/settings.py b/tests/settings.py new file mode 100644 index 0000000000000000000000000000000000000000..5f1ad520b9f95cb5304589a2300606661107f82b --- /dev/null +++ b/tests/settings.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +import os + +DIRNAME = os.path.dirname(__file__) +DEBUG = True +TEMPLATE_DEBUG = DEBUG +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': 'mydatabase' + } +} +STATIC_URL = '/static/' +STATICFILES_FINDERS = ( + 'django.contrib.staticfiles.finders.AppDirectoriesFinder', +) +INSTALLED_APPS = ( + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.sites', + 'django.contrib.staticfiles', + 'django.contrib.admin', + + 'newsbox', + 'myapp', +) +TEMPLATE_LOADERS = ( + 'django.template.loaders.filesystem.Loader', + 'django.template.loaders.app_directories.Loader', +) +# Required for Django 1.4+ +STATIC_URL = '/static/' +# Required for Django 1.5+ +SECRET_KEY = 'abc123' +USE_TZ = True +LANGUAGE_CODE = 'en' +LANGUAGES = [('en', 'English')] +ROOT_URLCONF = 'myapp.urls' diff --git a/tests/settings_all.py b/tests/settings_all.py new file mode 100644 index 0000000000000000000000000000000000000000..cd68248722654f080772f1991facf0a68270ac89 --- /dev/null +++ b/tests/settings_all.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from settings_cms import * + +INSTALLED_APPS = list(INSTALLED_APPS + ('myapp_all',)) +INSTALLED_APPS.remove('myapp_cms') +INSTALLED_APPS = tuple(INSTALLED_APPS) + +LANGUAGES = [('en', 'English',), ('fr', 'French',),] +ROOT_URLCONF = 'myapp_all.urls' +MIDDLEWARE_CLASSES=MIDDLEWARE_CLASSES+( + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.locale.LocaleMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', +) +CMS_PLACEHOLDER_CONF = { + 'main': { + 'name': "Main content", + 'plugins': ['NewsPlugin','TextPlugin'], + }, +} diff --git a/tests/settings_cms.py b/tests/settings_cms.py new file mode 100644 index 0000000000000000000000000000000000000000..aff9a8d54bce6b5db45f7c3764447b460bdd9aca --- /dev/null +++ b/tests/settings_cms.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from settings import * + +SITE_ID = 1 +INSTALLED_APPS = list(INSTALLED_APPS + ( + #cms requirements + 'cms', # django CMS itself + 'mptt', # utilities for implementing a modified pre-order traversal tree + 'menus', # helper for model independent hierarchical website navigation + 'south', # intelligent schema and data migrations + 'sekizai', # for javascript and css management + 'djangocms_admin_style', # for the admin skin. You **must** add 'djangocms_admin_style' in the list before 'django.contrib.admin'. + 'django.contrib.messages', # to enable messages framework (see :ref:`Enable messages <enable-messages>`) + 'djangocms_text_ckeditor', + 'newsbox_cms', + 'myapp_cms', +)) +INSTALLED_APPS.remove('myapp') +INSTALLED_APPS = tuple(INSTALLED_APPS) +MIDDLEWARE_CLASSES = ( + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.locale.LocaleMiddleware', + 'django.middleware.doc.XViewMiddleware', + 'django.middleware.common.CommonMiddleware', + 'cms.middleware.page.CurrentPageMiddleware', + 'cms.middleware.user.CurrentUserMiddleware', + 'cms.middleware.toolbar.ToolbarMiddleware', + 'cms.middleware.language.LanguageCookieMiddleware', +) +TEMPLATE_CONTEXT_PROCESSORS = ( + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + 'django.core.context_processors.i18n', + 'django.core.context_processors.request', + 'django.core.context_processors.media', + 'django.core.context_processors.static', + 'cms.context_processors.cms_settings', + 'sekizai.context_processors.sekizai', +) +CMS_TEMPLATES = ( + ('page.html', 'page'), +) +ROOT_URLCONF = 'myapp_cms.urls' +CMS_PLACEHOLDER_CONF = { + 'main': { + 'name': "Main content", + 'plugins': ['NewsPlugin',], + }, +} diff --git a/tests/settings_hvad.py b/tests/settings_hvad.py new file mode 100644 index 0000000000000000000000000000000000000000..f549c36a51563a7fa03ed56eba9aac21f06698f4 --- /dev/null +++ b/tests/settings_hvad.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from settings import * + +LANGUAGES = [('en', 'English'),('fr', 'French'),] +ROOT_URLCONF = 'myapp_hvad.urls' +MIDDLEWARE_CLASSES=( + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.locale.LocaleMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', +) + +INSTALLED_APPS = list(INSTALLED_APPS + ('hvad', 'myapp_hvad',)) +INSTALLED_APPS.remove('myapp') +INSTALLED_APPS = tuple(INSTALLED_APPS) diff --git a/tests/utils.py b/tests/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..17a8e09eacac1fbaa04695dcb6fbac07762d8922 --- /dev/null +++ b/tests/utils.py @@ -0,0 +1,256 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from myapp.models import News, NewsExpired, NewsSEO, NewsComplete, NewsExtended +from myapp_cms.models import News as cms_News, \ + NewsComplete as cms_NewsComplete, \ + NewsExtended as cms_NewsExtended +from myapp_hvad.models import News as hvad_News, \ + NewsComplete as hvad_NewsComplete, \ + NewsExtended as hvad_NewsExtended +from myapp_all.models import News as all_News, \ + NewsComplete as all_NewsComplete, \ + NewsExtended as all_NewsExtended +from cms.models.placeholdermodel import Placeholder +from cms.api import add_plugin + +def get_fields_values(newsTypes, newsType, i, inherited): + fields_values={} + if newsType in inherited : + return fields_values + inherited.append(newsType) + + for inheritedType in newsTypes[newsType]['overwrites']['inherit']: + fields_values.update(get_fields_values(newsTypes, inheritedType, i, [])) + if i in newsTypes[newsType]['overwrites']: + fields_values.update(newsTypes[newsType]['overwrites'][i]) + return fields_values + +def create_tests_data(app=None): + + #Translations of translatable fields + translations = { + 'en':{ + #default content is already in english + }, + 'fr':{ + 'newsbox_slug':'actualite-%d', + 'newsbox_title':'Actualité %d', + 'newsbox_summary':'Résumé de l\'actualité %d', + 'newsbox_body':'Corps de l\'actualité %d', + 'newsbox_meta_description':'Meta description de l\'actualité %d', + 'newsbox_meta_keywords':'motclef1, motclef2, actualite-%d', + 'content_field':'Contenu additionnel de l\'actualité %d', + 'seo_field':'SEO additionnel de l\'actualité %d', + }, + } + translatable_fields = translations['fr'].keys() + + #array of available NewsTypes + #for each NewsType, we define a subarray with the model to use and + #default fields values in "overwrites" which is a subarray too : + # - inherit is a list of other NewsTypes to get default fields.from their conf + # - key 0 is the default values for all news + # - keys 1 to N is an array with values to overwrite for news 1 to N. + # Can also contain a "languages" list with language code for translations. + #Only used for HVAD Models. Translations are in "translations" variable. + newsTypes = { + 'News' : { + 'model':News, + 'overwrites':{ + 'inherit':[], + #0 is for base values + 0:{ + 'newsbox_slug':'news-%d', + 'newsbox_title':'News %d', + 'newsbox_date':'2014-02-22T10:00:00+02:00', + 'newsbox_publication_start_date':'1985-07-02T10:00:00+02:00', + 'newsbox_published':True, + 'newsbox_summary':'Summary of the news %d', + 'newsbox_body':'Body of the news %d', + }, + 1:{}, + 2:{'newsbox_published':False}, + 3:{'newsbox_publication_start_date':'2020-01-01T10:00:00+02:00'}, + 4:{'newsbox_body':''}, + 5:{'newsbox_published':False}, + 6:{'newsbox_date':'2005-07-15T10:00:00+02:00'}, + 7:{'newsbox_date':'2020-01-01T10:00:00+02:00'}, + }, + }, + 'NewsExpired' : { + 'model':NewsExpired, + 'overwrites':{ + 'inherit':['News',], + 5:{ + 'newsbox_published':True, + 'newsbox_publication_end_date':'2000-01-01T10:00:00+02:00', + }, + }, + }, + 'NewsSEO' : { + 'model':NewsSEO, + 'overwrites':{ + 'inherit':['News',], + 0:{ + 'newsbox_indexed':True, + 'newsbox_meta_description':'Meta description of the news %d', + 'newsbox_meta_keywords':'keyword1, keyword2, news-%d', + }, + 6:{ + 'newsbox_indexed':False, + }, + }, + }, + 'NewsComplete' : { + 'model':NewsComplete, + 'overwrites':{ + 'inherit':['NewsExpired', 'NewsSEO'], + }, + }, + 'NewsExtended' : { + 'model':NewsExtended, + 'overwrites':{ + 'inherit':['NewsComplete'], + 0:{ + 'general_field':'Test', + 'content_field':'Extra content of the news %d', + 'seo_field':'Extra SEO of the news %d', + }, + } + }, + + #CMS Models + 'cms_News' : { + 'model':cms_News, + 'overwrites':{ + 'inherit':['News',], + 0:{ + 'newsbox_summary':'<p>Summary of the news %d</p>', + 'newsbox_body':'<p>Body of the news %d</p>', + }, + }, + }, + 'cms_NewsComplete' : { + 'model':cms_NewsComplete, + 'overwrites':{ + 'inherit':['NewsComplete', 'cms_News'], + }, + }, + 'cms_NewsExtended' : { + 'model':cms_NewsExtended, + 'overwrites':{ + 'inherit':['cms_NewsComplete'], + }, + }, + + #HVAD Models + 'hvad_News' : { + 'languages':['en', 'fr',], + 'model':hvad_News, + 'overwrites':{ + 'inherit':['News',], + }, + }, + 'hvad_NewsComplete' : { + 'languages':['en', 'fr',], + 'model':hvad_NewsComplete, + 'overwrites':{ + 'inherit':['NewsComplete', 'hvad_News'], + }, + }, + 'hvad_NewsExtended' : { + 'languages':['en', 'fr',], + 'model':hvad_NewsExtended, + 'overwrites':{ + 'inherit':['NewsExtended', 'hvad_NewsComplete'], + }, + }, + + #ALL Models + 'all_News' : { + 'languages':['en', 'fr',], + 'model':all_News, + 'overwrites':{ + 'inherit':['News',], + 0:{ + 'newsbox_summary':'<p>Summary of the news %d</p>', + 'newsbox_body':'<p>Body of the news %d</p>', + }, + }, + }, + 'all_NewsComplete' : { + 'languages':['en', 'fr',], + 'model':all_NewsComplete, + 'overwrites':{ + 'inherit':['NewsComplete', 'all_News'], + }, + }, + 'all_NewsExtended' : { + 'languages':['en', 'fr',], + 'model':all_NewsExtended, + 'overwrites':{ + 'inherit':['NewsExtended', 'all_NewsComplete'], + }, + }, + } + nb_news_a_creer = len(newsTypes['News']['overwrites'])-2 + for newsType, infos in newsTypes.items(): + if app and app +'_' not in newsType: + continue + base_kwargs = get_fields_values(newsTypes, newsType, 0, []) + + + print '\n%s\n' % newsType + '-' * len(newsType) + + for i in range(1, nb_news_a_creer+1): + + if not 'languages' in infos: + infos['languages'] = [None,] + + for lang in infos['languages']: + kwargs = base_kwargs.copy() + kwargs.update(get_fields_values(newsTypes, newsType, i, [])) + #Retrieve translated values if a lang is specified + if lang and lang in translations and translations[lang]: + for k in translations[lang]: + if k in kwargs : + if kwargs[k][0:3] == '<p>': + kwargs[k] = '<p>'+translations[lang][k]+'</p>' + else: + kwargs[k] = translations[lang][k] + + #Add the "nth" informations for fields which need it + for k in kwargs: + if type(kwargs[k]) in (str, unicode) and '%d' in kwargs[k]: + kwargs[k] = kwargs[k] % i + + try: + #Transform field into placeholders if needed + ph_names = getattr(infos['model']._meta, 'placeholder_field_names') + for ph_name in ph_names: + if not ph_name in kwargs: + continue + ph = Placeholder.objects.create(slot=ph_name) + add_plugin(ph, 'TextPlugin', lang if lang != None else 'en', body=kwargs[ph_name]) + kwargs[ph_name] = ph + except AttributeError: + pass + + translatable_values = {k:v + for k, v in kwargs.items() + if k in translatable_fields} + untranslatable_fields = list(set(kwargs) - set(translatable_fields)) + untranslatable_values = {k:v + for k, v in kwargs.items() + if k in untranslatable_fields} + + langstr = ' (%s)' % lang if lang else '' + print ' - %d%s : %s' % (i, langstr, kwargs['newsbox_title']) + if lang == infos['languages'][0]: + news = infos['model'](**untranslatable_values) + + if lang : + news.translate(lang) + for k in translatable_values: + setattr(news, k, translatable_values[k]) + news.save() diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000000000000000000000000000000000000..ba0e97be1897077859e2932365860e167cf177c3 --- /dev/null +++ b/tox.ini @@ -0,0 +1,77 @@ +[tox] +envlist= + py26-16, + py27-16, + py32-16, + py33-16, + py34-16, + + py26-cms30, + py27-cms30, +; cms seems to be not yet compatible with python 3.0 +; py32-cms30, +; py33-cms30, +; py34-cms30, + +[testenv] +changedir = {toxinidir}/tests + +[testenv:py26-16] +basepython = python2.6 +deps = -r{toxinidir}/test_requirements/django-1.6.txt +commands = ./runtests.sh myapp {posargs} + ./runtests.sh myapp_hvad {posargs} + +[testenv:py27-16] +basepython = python2.7 +deps = -r{toxinidir}/test_requirements/django-1.6.txt +commands = ./runtests.sh myapp {posargs} + ./runtests.sh myapp_hvad {posargs} + +[testenv:py32-16] +basepython = python3.2 +deps = -r{toxinidir}/test_requirements/django-1.6.txt +commands = ./runtests.sh myapp {posargs} +; ./runtests.sh myapp_hvad {posargs} + +[testenv:py33-16] +basepython = python3.3 +deps = -r{toxinidir}/test_requirements/django-1.6.txt +commands = ./runtests.sh myapp {posargs} +; ./runtests.sh myapp_hvad {posargs} + +[testenv:py34-16] +basepython = python3.4 +deps = -r{toxinidir}/test_requirements/django-1.6.txt +commands = ./runtests.sh myapp {posargs} +; ./runtests.sh myapp_hvad {posargs} + +[testenv:py26-cms30] +basepython = python2.6 +deps = -r{toxinidir}/test_requirements/django-1.6_cms-3.0.txt +commands = ./runtests.sh myapp_cms {posargs} + ./runtests.sh myapp_all {posargs} + +[testenv:py27-cms30] +basepython = python2.7 +deps = -r{toxinidir}/test_requirements/django-1.6_cms-3.0.txt +commands = ./runtests.sh myapp_cms {posargs} + ./runtests.sh myapp_all {posargs} + +[testenv:py32-cms30] +basepython = python3.2 +deps = -r{toxinidir}/test_requirements/django-1.6_cms-3.0.txt +commands = ./runtests.sh myapp_cms {posargs} + ./runtests.sh myapp_all {posargs} + +[testenv:py33-cms30] +basepython = python3.3 +deps = -r{toxinidir}/test_requirements/django-1.6_cms-3.0.txt +commands = ./runtests.sh myapp_cms {posargs} + ./runtests.sh myapp_all {posargs} + +[testenv:py34-cms30] +basepython = python3.4 +deps = -r{toxinidir}/test_requirements/django-1.6_cms-3.0.txt +commands = ./runtests.sh myapp_cms {posargs} + ./runtests.sh myapp_all {posargs}