diff --git a/README.rst b/README.rst index a68cbb8..12e3e3e 100644 --- a/README.rst +++ b/README.rst @@ -28,10 +28,13 @@ Run:: to perform the application's database migrations. -===== -Usage -===== +Configuration +============= + +The default Content Expiry changelist is filtered by a date range which is 30 days by default. This can be changed by setting a value in days as an integer in settings.py:: + + CMS_CONTENT_EXPIRY_DEFAULT_RANGEFILTER_DELTA=60 Testing @@ -41,20 +44,3 @@ To run all the tests the only thing you need to do is run pip install -r tests/requirements.txt python setup.py test - - -Documentation -============= - -We maintain documentation under the ``docs`` folder using rst format. - -To generate the HTML documentation you will need to install ``sphinx`` (``pip install sphinx``) and ``graphviz`` (as per -your operating system's package management system). You can then generate the docs using the following command: - -Run:: - - cd docs/ - make html - -This should generate all html files from rst documents under `docs/_build` folder, which can be browsed. - diff --git a/djangocms_content_expiry/admin.py b/djangocms_content_expiry/admin.py index 54f3139..e99d998 100644 --- a/djangocms_content_expiry/admin.py +++ b/djangocms_content_expiry/admin.py @@ -2,39 +2,41 @@ from django.contrib.contenttypes.models import ContentType from django.utils.translation import ugettext_lazy as _ -import datetime -from rangefilter.filters import DateRangeFilter - -from .filters import AuthorFilter, ContentTypeFilter, VersionStateFilter +from .filters import ( + AuthorFilter, + ContentExpiryDateRangeFilter, + ContentTypeFilter, + VersionStateFilter, +) +from .forms import ContentExpiryForm +from .helpers import get_rangefilter_expires_default from .models import ContentExpiry @admin.register(ContentExpiry) class ContentExpiryAdmin(admin.ModelAdmin): list_display = ['title', 'content_type', 'expires', 'version_state', 'version_author'] - # Disable automatically linking to the Expiry record - list_display_links = None - list_filter = (ContentTypeFilter, ('expires', DateRangeFilter), VersionStateFilter, AuthorFilter) + list_filter = (ContentTypeFilter, ('expires', ContentExpiryDateRangeFilter), VersionStateFilter, AuthorFilter) + form = ContentExpiryForm class Media: css = { - 'all': ('css/date_filter.css',) + 'all': ('djangocms_content_expiry/css/date_filter.css',) } - def get_queryset(self, request): - queryset = super().get_queryset(request) + def has_add_permission(self, *args, **kwargs): + # Entries are added automatically + return False - if 'expires__range' not in request.path: - default_gte, default_lte = self.get_rangefilter_expires_default(request) - queryset = queryset.filter(expires__range=(default_gte, default_lte)) - return queryset + def has_delete_permission(self, *args, **kwargs): + # Deletion should never be possible, the only way that a + # content expiry record could be deleted is via versioning. + return False - def get_rangefilter_expires_default(self, request): - start_date = datetime.datetime.now() - datetime.timedelta(30) - end_date = datetime.datetime.now() - return start_date, end_date + def get_rangefilter_expires_default(self, *args, **kwargs): + return get_rangefilter_expires_default() - def get_rangefilter_expires_title(self, request, field_path): + def get_rangefilter_expires_title(self, *args, **kwargs): return _("By Expiry Date Range") def title(self, obj): diff --git a/djangocms_content_expiry/apps.py b/djangocms_content_expiry/apps.py index f7fa1ff..7dccdbd 100644 --- a/djangocms_content_expiry/apps.py +++ b/djangocms_content_expiry/apps.py @@ -11,4 +11,5 @@ class DjangocmsContentExpiryConfig(AppConfig): def ready(self): from .handlers import create_content_expiry from .monkeypatch import admin as monkeypatch_admin # noqa: F401 + signals.post_version_operation.connect(create_content_expiry) diff --git a/djangocms_content_expiry/cms_config.py b/djangocms_content_expiry/cms_config.py index 7549fc1..abeff43 100644 --- a/djangocms_content_expiry/cms_config.py +++ b/djangocms_content_expiry/cms_config.py @@ -1,9 +1,68 @@ from django.conf import settings +from django.template.loader import render_to_string +from django.urls import reverse +from django.utils.html import format_html from cms.app_base import CMSAppConfig +from .constants import CONTENT_EXPIRY_EXPIRE_FIELD_LABEL + + +def get_moderation_content_expiry_link(obj): + """ + Return a user friendly button for viewing content expiry in the + actions section of the Moderation Request Admin Changelist + in djangocms-moderation. + + :param obj: A Moderation Request object supplied from the admin view table row + :return: A link to the expiry record if one exists + """ + version = obj.moderation_request.version + + # If a content expiry record exists we can go to it + if hasattr(version, "contentexpiry"): + view_endpoint = format_html( + "{}?collection__id__exact={}&_popup=1", + reverse("admin:djangocms_content_expiry_contentexpiry_change", args=[version.contentexpiry.pk]), + obj.pk, + ) + return render_to_string( + "djangocms_content_expiry/calendar_icon.html", {"url": view_endpoint, "field_id": f"contentexpiry_{obj.pk}"} + ) + return "" + + +def get_expiry_date(obj): + """ + A custom field to show the expiry date in the + Moderation Request Admin Changelist in djangocms-moderation. + + :param obj: A Moderation Request object supplied from the admin view table row + :return: The expiry date from the matching moderation request object + """ + version = obj.moderation_request.version + + if hasattr(version, "contentexpiry"): + return version.contentexpiry.expires + + +get_expiry_date.short_description = CONTENT_EXPIRY_EXPIRE_FIELD_LABEL + class ContentExpiryAppConfig(CMSAppConfig): + # Enable moderation to be able to "configure it" + djangocms_moderation_enabled = True + moderated_models = [] + moderation_request_changelist_actions = [ + get_moderation_content_expiry_link, + ] + moderation_request_changelist_fields = [ + get_expiry_date, + ] + # Enable versioning because moderation is versioning dependant + djangocms_versioning_enabled = True + versioning = [] + djangocms_content_expiry_enabled = getattr( settings, "DJANGOCMS_CONTENT_EXPIRY_ENABLED", True ) diff --git a/djangocms_content_expiry/conf.py b/djangocms_content_expiry/conf.py new file mode 100644 index 0000000..7d85691 --- /dev/null +++ b/djangocms_content_expiry/conf.py @@ -0,0 +1,6 @@ +from django.conf import settings + + +DEFAULT_RANGEFILTER_DELTA = getattr( + settings, "CMS_CONTENT_EXPIRY_DEFAULT_RANGEFILTER_DELTA", 30 +) diff --git a/djangocms_content_expiry/constants.py b/djangocms_content_expiry/constants.py new file mode 100644 index 0000000..625e431 --- /dev/null +++ b/djangocms_content_expiry/constants.py @@ -0,0 +1,4 @@ +from django.utils.translation import ugettext_lazy as _ + + +CONTENT_EXPIRY_EXPIRE_FIELD_LABEL = _("expiry date") diff --git a/djangocms_content_expiry/filters.py b/djangocms_content_expiry/filters.py index 4f8b95a..808e3bb 100644 --- a/djangocms_content_expiry/filters.py +++ b/djangocms_content_expiry/filters.py @@ -4,8 +4,9 @@ from djangocms_versioning.constants import PUBLISHED, VERSION_STATES from djangocms_versioning.versionables import _cms_extension +from rangefilter.filters import DateRangeFilter -from . import helpers +from .helpers import get_authors, get_rangefilter_expires_default class SimpleListMultiselectFilter(admin.SimpleListFilter): @@ -158,7 +159,7 @@ class AuthorFilter(admin.SimpleListFilter): def lookups(self, request, model_admin): from django.utils.encoding import force_text options = [] - for user in helpers.get_authors(): + for user in get_authors(): options.append( (force_text(user.pk), user.get_full_name() or user.get_username()) ) @@ -168,3 +169,16 @@ def queryset(self, request, queryset): if self.value(): return queryset.filter(created_by=self.value()).distinct() return queryset + + +class ContentExpiryDateRangeFilter(DateRangeFilter): + def queryset(self, request, queryset): + queryset = super().queryset(request, queryset) + + # By default the widget should default to show a default duration and not all content + # expiry records + if not any('expires__range' in seed for seed in request.GET): + default_gte, default_lte = get_rangefilter_expires_default() + queryset = queryset.filter(expires__range=(default_gte, default_lte)) + + return queryset diff --git a/djangocms_content_expiry/forms.py b/djangocms_content_expiry/forms.py new file mode 100644 index 0000000..8a3c555 --- /dev/null +++ b/djangocms_content_expiry/forms.py @@ -0,0 +1,24 @@ +from django import forms +from django.contrib.admin import widgets +from django.contrib.admin.sites import site + +from .models import ContentExpiry + + +class ForeignKeyReadOnlyWidget(widgets.ForeignKeyRawIdWidget): + """ + A Widget for displaying ForeignKeys in a read only interface rather than + in a +{{ link_label }} diff --git a/djangocms_content_expiry/templates/djangocms_content_expiry/calendar_icon.html b/djangocms_content_expiry/templates/djangocms_content_expiry/calendar_icon.html new file mode 100644 index 0000000..75897f6 --- /dev/null +++ b/djangocms_content_expiry/templates/djangocms_content_expiry/calendar_icon.html @@ -0,0 +1,2 @@ +{% load static i18n %} + diff --git a/djangocms_content_expiry/test_utils/polls/cms_config.py b/djangocms_content_expiry/test_utils/polls/cms_config.py index 07f9be9..c91b6b8 100644 --- a/djangocms_content_expiry/test_utils/polls/cms_config.py +++ b/djangocms_content_expiry/test_utils/polls/cms_config.py @@ -1,7 +1,8 @@ +from collections import OrderedDict + from cms.app_base import CMSAppConfig from cms.utils.i18n import get_language_tuple -from collections import OrderedDict from djangocms_versioning.datastructures import VersionableItem, default_copy from .models import PollContent diff --git a/setup.cfg b/setup.cfg index d300e1c..f8ba78b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -17,10 +17,11 @@ combine_as_imports = true include_trailing_comma = true balanced_wrapping = true skip = manage.py, migrations, .tox, node_modules -known_standard_library = mock +extra_standard_library = mock known_django = django known_cms = cms, menus -sections = FUTURE, STDLIB, DJANGO, CMS, THIRDPARTY, FIRSTPARTY, LIB, LOCALFOLDER +known_first_party = djangocms_content_expiry +sections = FUTURE, STDLIB, DJANGO, CMS, THIRDPARTY, FIRSTPARTY, LOCALFOLDER [coverage:run] branch = True diff --git a/test_settings.py b/test_settings.py index f849089..aae4c8b 100644 --- a/test_settings.py +++ b/test_settings.py @@ -4,6 +4,7 @@ "djangocms_content_expiry", "djangocms_content_expiry.test_utils.polls", "djangocms_versioning", + "djangocms_moderation", "rangefilter" ], "MIGRATION_MODULES": { @@ -11,6 +12,7 @@ "cms": None, "menus": None, "djangocms_versioning": None, + "djangocms_moderation": None, "djangocms_content_expiry": None, }, "CMS_PERMISSION": True, diff --git a/tests/requirements/requirements_base.txt b/tests/requirements/requirements_base.txt index ce80e39..64ee328 100644 --- a/tests/requirements/requirements_base.txt +++ b/tests/requirements/requirements_base.txt @@ -5,6 +5,7 @@ django-treebeard>=4.3 argparse dj-database-url djangocms-admin-style>=1.5 +django-admin-rangefilter django-sekizai>=0.7 django-classy-tags>=0.7.2 iptools @@ -16,10 +17,10 @@ django-app-helper mock>=2.0.0 django-formtools factory-boy -# Custom date range filter -django-admin-rangefilter +freezegun # Unreleased django-cms 4.0 compatible packages -https://github.com/divio/django-cms/tarball/66c70394c9e144281a0b47d93e3784d06318acf9#egg=django-cms -https://github.com/divio/djangocms-text-ckeditor/archive/support/4.0.x.zip -https://github.com/divio/djangocms-versioning/tarball/492d01c974e40b007b71e2a7e961a9019a0d5ac4#egg=djangocms-versioning \ No newline at end of file +https://github.com/divio/django-cms/tarball/release/4.0.x#egg=django-cms +https://github.com/divio/djangocms-text-ckeditor/tarball/support/4.0.x#egg=djangocms-text-ckeditor +https://github.com/divio/djangocms-versioning/tarball/master#egg=djangocms-versioning +https://github.com/django-cms/djangocms-moderation/tarball/release/1.0.x#egg=djangocms-moderation diff --git a/tests/test_admin.py b/tests/test_admin.py index 6483df6..1a45f7b 100644 --- a/tests/test_admin.py +++ b/tests/test_admin.py @@ -1,46 +1,99 @@ +import datetime +from unittest.mock import patch + from cms.test_utils.testcases import CMSTestCase -import datetime from djangocms_versioning.constants import ARCHIVED, DRAFT, PUBLISHED, UNPUBLISHED +from freezegun import freeze_time from djangocms_content_expiry.models import ContentExpiry from djangocms_content_expiry.test_utils.factories import UserFactory from djangocms_content_expiry.test_utils.polls.factories import PollContentExpiryFactory -class ContentExpiryChangelistTestCase(CMSTestCase): - def test_changelist_form_fields(self): +class ContentExpiryAdminViewsPermissionsTestCase(CMSTestCase): + + def setUp(self): + self.content_expiry = PollContentExpiryFactory() + + def test_add_permissions(self): + """ + Adding a content expiry record via the admin is not permitted + """ + endpoint = self.get_admin_url(ContentExpiry, "add") + + with self.login_user_context(self.get_superuser()): + response = self.client.get(endpoint) + + self.assertEqual(response.status_code, 403) + + def test_change_permissions(self): + """ + Changing a content expiry record via the admin is permitted + """ + endpoint = self.get_admin_url(ContentExpiry, "change", self.content_expiry.pk) + + with self.login_user_context(self.get_superuser()): + response = self.client.get(endpoint) + + self.assertEqual(response.status_code, 200) + + def test_delete_permissions(self): """ - Ensure that the form fields present match the model fields" + Deleting a content expiry record via the admin is not permitted """ + endpoint = self.get_admin_url(ContentExpiry, "delete", self.content_expiry.pk) + + with self.login_user_context(self.get_superuser()): + response = self.client.get(endpoint) + + self.assertEqual(response.status_code, 403) + + +class ContentExpiryChangeFormTestCase(CMSTestCase): + def test_change_form_fields(self): + """ + Ensure that the form fields present match the model fields + """ + content_expiry = PollContentExpiryFactory() + endpoint = self.get_admin_url(ContentExpiry, "change", content_expiry.pk) + with self.login_user_context(self.get_superuser()): - response = self.client.get(self.get_admin_url(ContentExpiry, "add")) + response = self.client.get(endpoint) self.assertEqual(response.status_code, 200) decoded_response = response.content.decode("utf-8") - self.assertIn('', decoded_response) - self.assertIn('', - decoded_response) + self.assertIn('name="created_by"', decoded_response) + self.assertIn('name="version"', decoded_response) + self.assertIn('name="expires_0"', decoded_response) + self.assertIn('name="expires_1"', decoded_response) + + +class ContentExpiryChangelistTestCase(CMSTestCase): def test_change_fields(self): """ Ensure the change list presents list display items from the admin file """ + endpoint = self.get_admin_url(ContentExpiry, "changelist") + with self.login_user_context(self.get_superuser()): - response = self.client.get(self.get_admin_url(ContentExpiry, "changelist")) + response = self.client.get(endpoint) context = response.context_data['cl'].list_display - self.assertEqual('title', context[1]) - self.assertEqual('content_type', context[2]) - self.assertEqual('expires', context[3]) - self.assertEqual('version_state', context[4]) - self.assertEqual('version_author', context[5]) + self.assertTrue('title' in context) + self.assertTrue('content_type' in context) + self.assertTrue('expires' in context) + self.assertTrue('version_state' in context) + self.assertTrue('version_author' in context) class ContentExpiryChangelistExpiryFilterTestCase(CMSTestCase): + + @freeze_time("2200-01-14") + @patch('djangocms_content_expiry.helpers.DEFAULT_RANGEFILTER_DELTA', 15) def test_expired_filter_default_setting(self): """ Default filter is to display all published content on page load @@ -55,51 +108,53 @@ def test_expired_filter_default_setting(self): # Record that is set to expire today expire_at_2 = from_date poll_content_2 = PollContentExpiryFactory(expires=expire_at_2, version__state=PUBLISHED) - version_2 = poll_content_2.version # Record that is set to expire tomorrow delta_3 = datetime.timedelta(days=1) expire_at_3 = from_date - delta_3 poll_content_3 = PollContentExpiryFactory(expires=expire_at_3, version__state=PUBLISHED) - version_3 = poll_content_3.version - # Record that is set to expire in 29 days - delta_4 = datetime.timedelta(days=29) + # Record that is set to expire in 1 day before the end date + delta_4 = datetime.timedelta(days=14) expire_at_4 = from_date - delta_4 poll_content_4 = PollContentExpiryFactory(expires=expire_at_4, version__state=PUBLISHED) - version_4 = poll_content_4.version - # Record that is set to expire in 30 days - delta_5 = datetime.timedelta(days=30) + # Record that is set to expire the same day as the end date + delta_5 = datetime.timedelta(days=15) expire_at_5 = from_date - delta_5 poll_content_5 = PollContentExpiryFactory(expires=expire_at_5, version__state=PUBLISHED) - poll_content_5.version - # Record that is set to expire in 31 days - delta_6 = datetime.timedelta(days=31) - expire_at_6 = from_date + delta_6 + # Record that is set to expire a day after the end date + delta_6 = datetime.timedelta(days=16) + expire_at_6 = from_date - delta_6 PollContentExpiryFactory(expires=expire_at_6, version__state=PUBLISHED) with self.login_user_context(self.get_superuser()): admin_endpoint = self.get_admin_url(ContentExpiry, "changelist") response = self.client.get(admin_endpoint) - # Only contents in the 30 date range should be returned + # Only contents in the date range should be returned self.assertQuerysetEqual( response.context["cl"].queryset, - [version_2.pk, version_3.pk, - version_4.pk], + [poll_content_2.version.pk, + poll_content_3.version.pk, + poll_content_4.version.pk, + poll_content_5.version.pk], transform=lambda x: x.pk, ordered=False, ) + @freeze_time("2200-01-14") + @patch('djangocms_content_expiry.helpers.DEFAULT_RANGEFILTER_DELTA', 15) def test_expired_filter_setting_expired_at_range_boundaries(self): """ - Check the boundaries of the Expired by date range filter. The dates are - set to check that only records due to expire are shown with a filter value set at 30 days + The boundaries of the Expired by date range filter are + set to check that only records due to expire are shown with a filter value set at a + different range to the setting DEFAULT_RANGEFILTER_DELTA. The reason the dates + need to differ ensure that we not just re-testing the default setting. """ from_date = datetime.datetime.now() - to_date = from_date - datetime.timedelta(days=30) + to_date = from_date - datetime.timedelta(days=110) # Record that is expired by 1 day delta_1 = datetime.timedelta(days=1) @@ -109,27 +164,24 @@ def test_expired_filter_setting_expired_at_range_boundaries(self): # Record that is set to expire today expire_at_2 = from_date poll_content_2 = PollContentExpiryFactory(expires=expire_at_2, version__state=PUBLISHED) - version_2 = poll_content_2.version # Record that is set to expire tomorrow delta_3 = datetime.timedelta(days=1) expire_at_3 = from_date - delta_3 poll_content_3 = PollContentExpiryFactory(expires=expire_at_3, version__state=PUBLISHED) - version_3 = poll_content_3.version - # Record that is set to expire in 29 days - delta_4 = datetime.timedelta(days=29) + # Record that is set to expire in 1 day before the end date + delta_4 = datetime.timedelta(days=109) expire_at_4 = from_date - delta_4 poll_content_4 = PollContentExpiryFactory(expires=expire_at_4, version__state=PUBLISHED) - version_4 = poll_content_4.version - # Record that is set to expire in 30 days - delta_5 = datetime.timedelta(days=30) + # Record that is set to expire the same day as the end date + delta_5 = datetime.timedelta(days=110) expire_at_5 = from_date - delta_5 - PollContentExpiryFactory(expires=expire_at_5, version__state=PUBLISHED) + poll_content_5 = PollContentExpiryFactory(expires=expire_at_5, version__state=PUBLISHED) - # Record that is set to expire in 31 days - delta_6 = datetime.timedelta(days=31) + # Record that is set to expire a day after the end date + delta_6 = datetime.timedelta(days=111) expire_at_6 = from_date - delta_6 PollContentExpiryFactory(expires=expire_at_6, version__state=PUBLISHED) @@ -137,13 +189,14 @@ def test_expired_filter_setting_expired_at_range_boundaries(self): url_date_range = f"?expires__range__gte={to_date.date()}&expires__range__lte={from_date.date()}" admin_endpoint = self.get_admin_url(ContentExpiry, "changelist") response = self.client.get(admin_endpoint + url_date_range) - # content_expiry_1, content_expiry_5, content_expiry_6 are not shown because they are outside of the set - # boundary range, content_expiry_1 is before the start and content_expiry_5 and content_expiry_6 is - # outside of the range. + + # Only contents in the date range should be returned self.assertQuerysetEqual( response.context["cl"].queryset, - [version_2.pk, version_3.pk, - version_4.pk], + [poll_content_2.version.pk, + poll_content_3.version.pk, + poll_content_4.version.pk, + poll_content_5.version.pk], transform=lambda x: x.pk, ordered=False, ) diff --git a/tests/test_cms_config.py b/tests/test_cms_config.py new file mode 100644 index 0000000..73a8ee2 --- /dev/null +++ b/tests/test_cms_config.py @@ -0,0 +1,58 @@ +from django.apps import apps +from django.contrib import admin +from django.test import RequestFactory + +from cms.test_utils.testcases import CMSTestCase + +from djangocms_moderation.cms_config import ModerationExtension +from djangocms_moderation.models import ModerationRequestTreeNode + +from djangocms_content_expiry.cms_config import ContentExpiryAppConfig +from djangocms_content_expiry.constants import CONTENT_EXPIRY_EXPIRE_FIELD_LABEL + + +class ModerationConfigDependancyTestCase(CMSTestCase): + def test_moderation_config_admin_controls_exist(self): + """ + Moderation controls are required for the content expiry records to be viewed, + ensure that they exist, a failure here means that the implementation in moderation + may have been changed + """ + moderation_extension = ModerationExtension() + + self.assertTrue(hasattr(moderation_extension, "moderation_request_changelist_actions")) + self.assertTrue(hasattr(moderation_extension, "moderation_request_changelist_fields")) + self.assertTrue( + hasattr(moderation_extension, "handle_moderation_request_changelist_actions") + and callable(moderation_extension.handle_moderation_request_changelist_actions) + ) + self.assertTrue( + hasattr(moderation_extension, "handle_moderation_request_changelist_fields") + and callable(moderation_extension.handle_moderation_request_changelist_fields) + ) + + def test_moderation_config_admin_controls_are_compiled_by_moderation(self): + moderation = apps.get_app_config("djangocms_moderation") + content_expiry_actions = ContentExpiryAppConfig.moderation_request_changelist_actions + content_expiry_fields = ContentExpiryAppConfig.moderation_request_changelist_fields + + self.assertListEqual( + moderation.cms_extension.moderation_request_changelist_actions, + content_expiry_actions, + ) + self.assertListEqual( + moderation.cms_extension.moderation_request_changelist_fields, + content_expiry_fields, + ) + + def test_moderation_request_contains_added_admin_fields(self): + """ + Ensure that the admin field is added as expected + """ + moderation_admin = admin.site._registry[ModerationRequestTreeNode] + + request = RequestFactory().get("/") + list_display = moderation_admin.get_list_display(request) + + self.assertIn('get_expiry_date', list_display) + self.assertEqual(CONTENT_EXPIRY_EXPIRE_FIELD_LABEL, moderation_admin.get_expiry_date.short_description) diff --git a/tests/test_helpers.py b/tests/test_helpers.py index 15f98d7..3069519 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -1,10 +1,18 @@ +from datetime import datetime +from unittest.mock import patch + from cms.test_utils.testcases import CMSTestCase -from djangocms_content_expiry.helpers import get_authors +from freezegun import freeze_time + +from djangocms_content_expiry.helpers import ( + get_authors, + get_rangefilter_expires_default, +) from djangocms_content_expiry.test_utils.polls.factories import PollContentExpiryFactory -class ContentExpiryHelpersTestCase(CMSTestCase): +class ContentExpiryAuthorHelperTestCase(CMSTestCase): def test_get_authors_query_burden(self): """ Ensure that the get_authors helper does not execute multiple queries @@ -13,3 +21,19 @@ def test_get_authors_query_burden(self): with self.assertNumQueries(1): users = get_authors() self.assertEqual(users.count(), 20) + + +class ContentExpiryDefaultRangeHelperTestCase(CMSTestCase): + + @patch('djangocms_content_expiry.helpers.DEFAULT_RANGEFILTER_DELTA', 5) + def test_default_range_is_returned_from_setting_value(self): + """ + By default the range returned should be changed by the setting: + CMS_CONTENT_EXPIRY_DEFAULT_RANGEFILTER_DELTA mapped in conf.py as + DEFAULT_RANGEFILTER_DELTA + """ + with freeze_time("2100-10-10 00:00:00", tz_offset=0): + start, end = get_rangefilter_expires_default() + + self.assertEqual(start, datetime(2100, 10, 5, 0, 0)) + self.assertEqual(end, datetime(2100, 10, 10, 0, 0)) diff --git a/tests/test_monkeypatch.py b/tests/test_monkeypatch.py index b77d0a4..eb0b0ba 100644 --- a/tests/test_monkeypatch.py +++ b/tests/test_monkeypatch.py @@ -1,14 +1,18 @@ +import datetime + from django.contrib import admin +from django.test import RequestFactory from cms.test_utils.testcases import CMSTestCase -import datetime from djangocms_versioning.constants import PUBLISHED +from djangocms_content_expiry.constants import CONTENT_EXPIRY_EXPIRE_FIELD_LABEL from djangocms_content_expiry.test_utils.polls.factories import PollContentExpiryFactory class ContentExpiryMonkeyPatchTesCase(CMSTestCase): + def test_extended_admin_monkey_patch_list_display_expires(self): """ Monkey patch should add expiry column and values to admin menu list display @@ -17,11 +21,12 @@ def test_extended_admin_monkey_patch_list_display_expires(self): delta_1 = datetime.timedelta(days=1) expire_at_1 = from_date + delta_1 - version = PollContentExpiryFactory(expires=expire_at_1, version__state=PUBLISHED) - request = self.get_request("/") + content_expiry = PollContentExpiryFactory(expires=expire_at_1, version__state=PUBLISHED) + version_admin = admin.site._registry[content_expiry.version.versionable.version_model_proxy] - version_admin = admin.site._registry[type(version)] + request = RequestFactory().get("/") list_display = version_admin.get_list_display(request) # List display field should have been added by monkeypatch - self.assertIn('expires', list_display) + self.assertIn('expire', list_display) + self.assertEqual(CONTENT_EXPIRY_EXPIRE_FIELD_LABEL, version_admin.expire.short_description)