From 6a0972ded8c87034d0d0c46273e71013ea903a38 Mon Sep 17 00:00:00 2001 From: Serghei Mihai Date: Tue, 24 Oct 2017 09:56:49 +0200 Subject: [PATCH] add support of Django 1.11 (#19614) --- corbo/api_urls.py | 6 ++-- corbo/manage_urls.py | 6 ++-- corbo/settings.py | 32 ++++++++++++++++++--- corbo/urls.py | 9 +++--- corbo/utils.py | 5 ++-- corbo/views.py | 5 ++-- requirements.txt | 2 +- setup.py | 2 +- tests/test_manager.py | 71 ++++++++++++++++++++++++----------------------- tests/test_subscribers.py | 15 +++++----- tox.ini | 3 +- 11 files changed, 91 insertions(+), 65 deletions(-) diff --git a/corbo/api_urls.py b/corbo/api_urls.py index ceddfd4..8d67d33 100644 --- a/corbo/api_urls.py +++ b/corbo/api_urls.py @@ -14,13 +14,13 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from django.conf.urls import patterns, url +from django.conf.urls import url from .api_views import NewslettersView, SubscriptionsView, SubscribeView -urlpatterns = patterns('', +urlpatterns = [ url(r'^newsletters/', NewslettersView.as_view(), name='newsletters'), url(r'^subscriptions/', SubscriptionsView.as_view(), name='subscriptions'), url(r'^subscribe/', SubscribeView.as_view(), name='subscribe'), -) +] diff --git a/corbo/manage_urls.py b/corbo/manage_urls.py index 7b126d0..0b20988 100644 --- a/corbo/manage_urls.py +++ b/corbo/manage_urls.py @@ -1,11 +1,11 @@ -from django.conf.urls import patterns, include, url +from django.conf.urls import url from .views import add_announce, edit_announce, delete_announce, \ add_category, edit_category, view_category, delete_category, manage, \ subscriptions_import, view_announce, email_announce, sms_announce, \ menu_json -urlpatterns = patterns('', +urlpatterns = [ url(r'^$', manage, name='manage'), url(r'^category/(?P[\w-]+)/announce/$', add_announce, name='add_announce'), @@ -30,4 +30,4 @@ urlpatterns = patterns('', url(r'^category/(?P[\w-]+)/import-subscriptions/$', subscriptions_import, name='subscriptions-import'), url(r'^menu.json$', menu_json), -) +] diff --git a/corbo/settings.py b/corbo/settings.py index 5b244ca..a68f624 100644 --- a/corbo/settings.py +++ b/corbo/settings.py @@ -54,6 +54,28 @@ MIDDLEWARE_CLASSES = ( 'django.middleware.clickjacking.XFrameOptionsMiddleware', ) +# Templates +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [ + ], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.contrib.auth.context_processors.auth', + 'django.template.context_processors.debug', + 'django.template.context_processors.i18n', + 'django.template.context_processors.media', + 'django.template.context_processors.static', + 'django.template.context_processors.tz', + 'django.contrib.messages.context_processors.messages', + 'django.template.context_processors.request' + ], + }, + }, +] + ROOT_URLCONF = 'corbo.urls' WSGI_APPLICATION = 'corbo.wsgi.application' @@ -82,11 +104,13 @@ USE_L10N = True USE_TZ = True -STATICFILES_FINDERS = global_settings.STATICFILES_FINDERS + ('gadjo.finders.XStaticFinder',) +STATICFILES_FINDERS = tuple(global_settings.STATICFILES_FINDERS) + ('gadjo.finders.XStaticFinder',) -if not 'django.template.context_processors.request' in global_settings.TEMPLATE_CONTEXT_PROCESSORS: - TEMPLATE_CONTEXT_PROCESSORS = ('django.template.context_processors.request',) + \ - global_settings.TEMPLATE_CONTEXT_PROCESSORS +# compatibility with django<1.10 +if hasattr(global_settings, 'TEMPLATE_CONTEXT_PROCESSORS'): + if not 'django.template.context_processors.request' in global_settings.TEMPLATE_CONTEXT_PROCESSORS: + TEMPLATE_CONTEXT_PROCESSORS = ('django.template.context_processors.request',) + \ + global_settings.TEMPLATE_CONTEXT_PROCESSORS # Static files (CSS, JavaScript, Images) diff --git a/corbo/urls.py b/corbo/urls.py index 1f3de1b..af2a9a0 100644 --- a/corbo/urls.py +++ b/corbo/urls.py @@ -1,5 +1,5 @@ from django.conf import settings -from django.conf.urls import patterns, include, url +from django.conf.urls import include, url from django.conf.urls.static import static from django.contrib.staticfiles.urls import staticfiles_urlpatterns from django.contrib import admin @@ -15,7 +15,8 @@ from api_urls import urlpatterns as api_urls import ckeditor.views as ckeditor_views -urlpatterns = patterns('', + +urlpatterns = [ url(r'^$', homepage, name='home'), url(r'^atom$', atom, name='atom'), url(r'^manage/', decorated_includes(manager_required, @@ -32,10 +33,10 @@ urlpatterns = patterns('', name='ckeditor_upload'), url(r'^ckeditor/browse/', never_cache(staff_member_required(ckeditor_views.browse)), name='ckeditor_browse'), -) +] if 'mellon' in settings.INSTALLED_APPS: - urlpatterns += patterns('', url(r'^accounts/mellon/', include('mellon.urls'))) + urlpatterns.append(url(r'^accounts/mellon/', include('mellon.urls'))) urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) urlpatterns += staticfiles_urlpatterns() diff --git a/corbo/utils.py b/corbo/utils.py index 5e5f0d0..8be5589 100644 --- a/corbo/utils.py +++ b/corbo/utils.py @@ -24,7 +24,7 @@ from emails.django import Message from lxml import etree from django.conf import settings -from django.template import loader, Context +from django.template import loader from django.utils.translation import activate from django.core.files.storage import DefaultStorage from django.core.urlresolvers import reverse @@ -45,8 +45,7 @@ def send_email(title, content, destinations, category_id): template = loader.get_template('corbo/announce.html') message = Message(subject=title, mail_from=settings.DEFAULT_FROM_EMAIL, html=template.render( - Context({'content': content, - 'unsubscribe_link_placeholder': UNSUBSCRIBE_LINK_PLACEHOLDER}))) + {'content': content, 'unsubscribe_link_placeholder': UNSUBSCRIBE_LINK_PLACEHOLDER})) # perform transformations in message html, like inline css parsing message.transformer.apply_to_images(func=transform_image_src) diff --git a/corbo/views.py b/corbo/views.py index b657fe6..6fe66d0 100644 --- a/corbo/views.py +++ b/corbo/views.py @@ -51,6 +51,7 @@ def logout(request, next_page=None): class HomepageView(RedirectView): pattern_name = 'manage' + permanent = True homepage = HomepageView.as_view() @@ -71,7 +72,7 @@ class AnnounceCreateView(CreateView): def get_context_data(self, **kwargs): context = super(AnnounceCreateView, self).get_context_data(**kwargs) - context['category'] = kwargs['form'].initial['category'] + context['category'] = context['form'].initial['category'] return context @@ -84,7 +85,7 @@ class AnnounceEditView(UpdateView): def get_context_data(self, **kwargs): context = super(AnnounceEditView, self).get_context_data(**kwargs) - category_id = kwargs['form'].initial['category'] + category_id = context['form'].initial['category'] context['category'] = models.Category.objects.get(pk=category_id) return context diff --git a/requirements.txt b/requirements.txt index f134314..ad6f7f2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Django>1.7, <1.9 +Django>1.7, <1.12 django-ckeditor<4.5.3 djangorestframework>=3.3,<3.4 html2text diff --git a/setup.py b/setup.py index f03e1e6..fba55d2 100644 --- a/setup.py +++ b/setup.py @@ -93,7 +93,7 @@ setup( 'Programming Language :: Python', 'Programming Language :: Python :: 2', ], - install_requires=['django>1.7, <1.9', + install_requires=['django>1.7, <1.12', 'django-ckeditor<4.5.3', 'djangorestframework>=3.3,<3.4', 'html2text', diff --git a/tests/test_manager.py b/tests/test_manager.py index 1610bcf..4bc08d8 100644 --- a/tests/test_manager.py +++ b/tests/test_manager.py @@ -20,7 +20,7 @@ def admin_user(): return user def login(app, username='admin', password='admin'): - login_page = app.get('/login/') + login_page = app.get(reverse('auth_login')) login_form = login_page.forms[0] login_form['username'] = username login_form['password'] = password @@ -30,18 +30,18 @@ def login(app, username='admin', password='admin'): def test_unlogged_access(app): # connect while not being logged in - assert app.get('/', status=301).location == 'http://testserver/manage/' - assert app.get('/manage/', status=302).location == 'http://testserver/login/?next=/manage/' + assert app.get('/', status=301).location.endswith(reverse('manage')) + assert app.get('/manage/', status=302).location.endswith(reverse('auth_login') + '?next=/manage/') def test_access(app, admin_user): app = login(app) - resp = app.get('/manage/', status=200) + resp = app.get(reverse('manage'), status=200) assert 'New category' in resp.body def test_logout(app, admin_user): app = login(app) - app.get('/logout/') - assert app.get('/', status=301).location == 'http://testserver/manage/' + app.get(reverse('auth_logout')) + assert app.get('/', status=301).location.endswith(reverse('manage')) def test_create_category(app, admin_user): app = login(app) @@ -52,21 +52,21 @@ def test_create_category(app, admin_user): category_form['name'] = 'Alerts' resp = category_form.submit() assert resp.status_int == 302 - assert resp.location == 'http://testserver/manage/' - resp = app.get('http://testserver/manage/') + assert resp.location.endswith(reverse('manage')) + resp = resp.follow() assert 'Alerts' in resp.content def test_edit_category(app, admin_user): app = login(app) - resp = app.get('/manage/') + resp = app.get(reverse('manage')) assert 'New category' in resp.content category_page = resp.click('New category') category_form = category_page.forms[0] category_form['name'] = 'Alerts' resp = category_form.submit() assert resp.status_int == 302 - assert resp.location == 'http://testserver/manage/' - resp = app.get('http://testserver/manage/') + assert resp.location.endswith(reverse('manage')) + resp = app.get(reverse('manage')) assert 'Alerts' in resp.content assert '0 announces' in resp.content assert '0 subscriptions' in resp.content @@ -77,19 +77,19 @@ def test_edit_category(app, admin_user): edit_form['name'] = 'New Alerts' resp = edit_form.submit() assert resp.status_int == 302 - assert resp.location == 'http://testserver/manage/category/alerts/' + assert resp.location.endswith(reverse('view_category', kwargs={'slug': 'alerts'})) def test_delete_category(app, admin_user): app = login(app) - resp = app.get('/manage/') + resp = app.get(reverse('manage')) assert 'New category' in resp.content category_page = resp.click('New category') category_form = category_page.forms[0] category_form['name'] = 'Alerts' resp = category_form.submit() assert resp.status_int == 302 - assert resp.location == 'http://testserver/manage/' - resp = app.get('http://testserver/manage/') + assert resp.location.endswith(reverse('manage')) + resp = app.get(reverse('manage')) assert 'Alerts' in resp.content assert '0 announces' in resp.content assert '0 subscriptions' in resp.content @@ -99,7 +99,7 @@ def test_delete_category(app, admin_user): delete_form = delete_page.forms[0] resp = delete_form.submit() assert resp.status_int == 302 - assert resp.location == 'http://testserver/manage/' + assert resp.location.endswith(reverse('manage')) def test_create_announce(app, admin_user): app = login(app) @@ -110,8 +110,8 @@ def test_create_announce(app, admin_user): category_form['name'] = 'Alerts' resp = category_form.submit() assert resp.status_int == 302 - assert resp.location == 'http://testserver/manage/' - resp = app.get('http://testserver/manage/') + assert resp.location.endswith(reverse('manage')) + resp = app.get(reverse('manage')) assert 'Alerts' in resp.content resp = resp.click('Alerts') assert 'New announce' in resp.content @@ -121,8 +121,9 @@ def test_create_announce(app, admin_user): announce_form['text'] = 'announce content' resp = announce_form.submit() assert resp.status_int == 302 - assert resp.location == 'http://testserver/manage/category/alerts/' - resp = app.get('http://testserver/manage/category/alerts/') + category_url = reverse('view_category', kwargs={'slug': 'alerts'}) + assert resp.location.endswith(category_url) + resp = resp.follow() assert 'First announce' in resp.content def test_edit_announce(app, admin_user): @@ -134,7 +135,7 @@ def test_edit_announce(app, admin_user): category_form['name'] = 'Alerts' resp = category_form.submit() assert resp.status_int == 302 - assert resp.location == 'http://testserver/manage/' + assert resp.location.endswith(reverse('manage')) resp = app.get(resp.location) resp = resp.click('Alerts') assert 'New announce' in resp.content @@ -144,8 +145,8 @@ def test_edit_announce(app, admin_user): announce_form['text'] = 'announce content' resp = announce_form.submit() assert resp.status_int == 302 - assert resp.location == 'http://testserver/manage/category/alerts/' - resp = app.get(resp.location) + assert resp.location.endswith(reverse('view_category', kwargs={'slug': 'alerts'})) + resp = resp.follow() assert 'First announce' in resp.content announce_page = resp.click('First announce') assert 'First announce' in announce_page.content @@ -158,7 +159,7 @@ def test_edit_announce(app, admin_user): edit_form['expiration_time'] = '2017-12-31 23:00:00' resp = edit_form.submit() assert resp.status_int == 302 - assert resp.location == 'http://testserver/manage/announce/1/' + assert resp.location.endswith(reverse('view_announce', kwargs={'pk': 1})) # simulate announce deliver broadcast = Broadcast.objects.get(announce__pk=1) @@ -190,8 +191,8 @@ def test_delete_announce(app, admin_user): category_form['name'] = 'Alerts' resp = category_form.submit() assert resp.status_int == 302 - assert resp.location == 'http://testserver/manage/' - resp = app.get('http://testserver/manage/') + assert resp.location.endswith(reverse('manage')) + resp = app.get(reverse('manage')) resp = resp.click('Alerts') assert 'New announce' in resp.content announce_page = resp.click('New announce') @@ -200,8 +201,8 @@ def test_delete_announce(app, admin_user): announce_form['text'] = 'announce content' resp = announce_form.submit() assert resp.status_int == 302 - assert resp.location == 'http://testserver/manage/category/alerts/' - resp = app.get('http://testserver/manage/category/alerts/') + assert resp.location.endswith(reverse('view_category', kwargs={'slug': 'alerts'})) + resp = resp.follow() assert 'First announce' in resp.content resp = resp.click('First announce') assert 'Delete' in resp.content @@ -210,7 +211,7 @@ def test_delete_announce(app, admin_user): announce_delete_form = announce_delete_page.forms[0] resp = announce_delete_form.submit() assert resp.status_int == 302 - assert resp.location == 'http://testserver/manage/category/alerts/' + assert resp.location.endswith(reverse('view_category', kwargs={'slug': 'alerts'})) def test_email_announce(app, admin_user): app = login(app) @@ -221,8 +222,8 @@ def test_email_announce(app, admin_user): category_form['name'] = 'Alerts' resp = category_form.submit() assert resp.status_int == 302 - assert resp.location == 'http://testserver/manage/' - resp = app.get('http://testserver/manage/') + assert resp.location.endswith(reverse('manage')) + resp = resp.follow() resp = resp.click('Alerts') assert 'New announce' in resp.content announce_page = resp.click('New announce') @@ -231,8 +232,8 @@ def test_email_announce(app, admin_user): announce_form['text'] = 'announce content' resp = announce_form.submit() assert resp.status_int == 302 - assert resp.location == 'http://testserver/manage/category/alerts/' - resp = app.get(resp.location) + assert resp.location.endswith(reverse('view_category', kwargs={'slug': 'alerts'})) + resp = resp.follow() assert 'First announce' in resp.content resp = resp.click('First announce') assert 'Send test email' in resp.content @@ -246,7 +247,7 @@ def test_email_announce(app, admin_user): assert 'Cancel' in resp.content resp = send_form.submit() assert resp.status_int == 302 - assert resp.location == 'http://testserver/manage/announce/1/' + assert resp.location.endswith(reverse('view_announce', kwargs={'pk': '1'})) @mock.patch('corbo.utils.requests.post') def test_sms_announce(mocked_post, app, admin_user, settings): @@ -326,7 +327,7 @@ def test_sms_announce_with_invalid_gateway_url(app, admin_user, settings, caplog announce_form['text'] = 'announce content' resp = announce_form.submit() assert resp.status_int == 302 - assert resp.location == 'http://testserver/manage/category/alerts/' + assert resp.location.endswith(reverse('view_category', kwargs={'slug': 'alerts'})) resp = resp.follow() assert 'First announce' in resp.content settings.SMS_GATEWAY_URL='invalid_url' diff --git a/tests/test_subscribers.py b/tests/test_subscribers.py index 4c3d611..5ba6d33 100644 --- a/tests/test_subscribers.py +++ b/tests/test_subscribers.py @@ -1,7 +1,6 @@ import pytest -from webtest import TestApp, Upload +from webtest import Upload -from django.core.wsgi import get_wsgi_application from django.utils.text import slugify from django.core.urlresolvers import reverse from django.contrib.auth import get_user_model @@ -42,8 +41,8 @@ def login(app, username='admin', password='password'): assert resp.status_int == 302 return app -def test_subscribe_from_csv(admin, categories): - app = login(TestApp(get_wsgi_application())) +def test_subscribe_from_csv(app, admin, categories): + app = login(app) for c in categories: page = app.get(reverse('subscriptions-import', kwargs={'slug': c.slug})) form = page.form @@ -52,8 +51,8 @@ def test_subscribe_from_csv(admin, categories): assert res.status_code == 302 assert Subscription.objects.filter(category=c).count() == len(CSV_CONTENT.splitlines()) -def test_subscribe_from_csv_with_empty_lines(admin, categories): - app = login(TestApp(get_wsgi_application())) +def test_subscribe_from_csv_with_empty_lines(app, admin, categories): + app = login(app) content = CSV_CONTENT + '\n\n\n' for c in categories: page = app.get(reverse('subscriptions-import', kwargs={'slug': c.slug})) @@ -63,8 +62,8 @@ def test_subscribe_from_csv_with_empty_lines(admin, categories): assert res.status_code == 302 assert Subscription.objects.filter(category=c).count() == len(CSV_CONTENT.splitlines()) -def test_subscribe_with_invalid_email(admin, categories): - app = login(TestApp(get_wsgi_application())) +def test_subscribe_with_invalid_email(app, admin, categories): + app = login(app) content = CSV_CONTENT + '\nwrong, Wrong user,' for category in categories: page = app.get(reverse('subscriptions-import', kwargs={'slug': category.slug})) diff --git a/tox.ini b/tox.ini index 740b6c6..2d4655e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = coverage-django18 +envlist = coverage-django18,coverage-django111 [testenv] usedevelop = @@ -10,6 +10,7 @@ setenv = coverage: COVERAGE=--junitxml=test_results.xml --cov-report xml --cov=corbo/ --cov-config .coveragerc deps = django18: django>=1.8,<1.9 + django111: django>=1.11,<1.12 http://git.entrouvert.org/hobo.git/snapshot/hobo-master.tar.gz pytest-cov pytest-django>=3.1.1 -- 2.15.1