diff --git a/corbo/api_views.py b/corbo/api_views.py index fa4d894..878cc3f 100644 --- a/corbo/api_views.py +++ b/corbo/api_views.py @@ -20,6 +20,7 @@ from collections import defaultdict from django.core.exceptions import PermissionDenied from django.db.models import Q from django.db import transaction +from django.utils.encoding import force_text from rest_framework.views import APIView from rest_framework.response import Response @@ -90,7 +91,7 @@ class SubscriptionsView(APIView): mobile = request.GET.get('mobile') if not uuid: raise PermissionDenied('Uuid parameter required') - data = json.loads(request.body) + data = json.loads(force_text(request.body)) for subscription in data: self.update_subscriptions(subscription['id'], subscription['transports'], uuid, email, mobile) @@ -114,7 +115,7 @@ class SubscribeView(SubscriptionsView): uuid = request.GET.get('uuid') if not uuid: raise PermissionDenied('Uuid parameter required') - data = json.loads(request.body) + data = json.loads(force_text(request.body)) self.update_subscriptions(data['category_id'], data['transports'], uuid, email, mobile) diff --git a/corbo/forms.py b/corbo/forms.py index 831c540..80075a0 100644 --- a/corbo/forms.py +++ b/corbo/forms.py @@ -2,10 +2,12 @@ import csv from django import forms from django.utils.translation import ugettext_lazy as _ +from django.utils.encoding import force_text from django.utils.text import slugify from django.core.exceptions import ObjectDoesNotExist from django.core import validators from django.core.exceptions import ValidationError +from django.utils import six from .models import Announce, Category, Broadcast, channel_choices from . import widgets @@ -67,6 +69,8 @@ class SubscriptionsImportForm(forms.Form): def clean_subscribers(self, *args, **kwargs): subscribers = [] + if six.PY3: + self.cleaned_data['subscribers'] = force_text(self.cleaned_data['subscribers'].read()).splitlines() reader = csv.reader(self.cleaned_data['subscribers']) for idx, row in enumerate(reader, 1): if not row or not row[0]: diff --git a/corbo/models.py b/corbo/models.py index 1830878..fdc3efc 100644 --- a/corbo/models.py +++ b/corbo/models.py @@ -8,6 +8,7 @@ import requests import feedparser from django.utils import timezone +from django.utils.encoding import force_text from django.conf import settings from django.db import models from django.core.files.storage import DefaultStorage @@ -115,7 +116,7 @@ class Announce(models.Model): storage.save(image_name, io.BytesIO(new_content)) img.attrib['src'] = storage.url(image_name) - self.text = etree.tostring(html_tree) + self.text = force_text(etree.tostring(html_tree)) super(Announce, self).save(*args, **kwargs) @property diff --git a/corbo/settings.py b/corbo/settings.py index 4a253bc..0571cd4 100644 --- a/corbo/settings.py +++ b/corbo/settings.py @@ -199,4 +199,4 @@ CORBO_PHONE_SEARCH_DIGITS = 9 local_settings_file = os.environ.get('CORBO_SETTINGS_FILE', os.path.join(os.path.dirname(__file__), 'local_settings.py')) if os.path.exists(local_settings_file): - execfile(local_settings_file) + exec(open(local_settings_file).read()) diff --git a/corbo/urls.py b/corbo/urls.py index af2a9a0..f241002 100644 --- a/corbo/urls.py +++ b/corbo/urls.py @@ -10,8 +10,8 @@ from django.contrib.admin.views.decorators import staff_member_required from .urls_utils import decorated_includes, manager_required from .views import homepage, atom, unsubscribe, unsubscription_done, login, logout -from manage_urls import urlpatterns as manage_urls -from api_urls import urlpatterns as api_urls +from .manage_urls import urlpatterns as manage_urls +from .api_urls import urlpatterns as api_urls import ckeditor.views as ckeditor_views diff --git a/corbo/utils.py b/corbo/utils.py index 321b89a..530ab16 100644 --- a/corbo/utils.py +++ b/corbo/utils.py @@ -18,7 +18,6 @@ import os import re import logging import requests -import urlparse import hashlib from html2text import HTML2Text from emails.django import Message @@ -30,6 +29,7 @@ from django.utils.translation import activate from django.core.files.storage import DefaultStorage from django.core.urlresolvers import reverse from django.core import signing +from django.utils.six.moves.urllib import parse as urlparse UNSUBSCRIBE_LINK_PLACEHOLDER = '%%UNSUBSCRIBE_LINK_PLACEHOLDER%%' diff --git a/corbo/views.py b/corbo/views.py index ff07bb7..c1e748d 100644 --- a/corbo/views.py +++ b/corbo/views.py @@ -1,4 +1,3 @@ -import urllib import json from django.conf import settings @@ -12,6 +11,7 @@ from django.contrib.syndication.views import Feed from django.shortcuts import resolve_url from django.utils.encoding import force_text from django.utils.feedgenerator import Atom1Feed as DjangoAtom1Feed +from django.utils.http import quote from django.http import HttpResponseRedirect, HttpResponse, Http404 from django.contrib.auth import logout as auth_logout from django.contrib.auth import views as auth_views @@ -19,7 +19,7 @@ from django.contrib import messages from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ngettext -import models +from . import models from .forms import AnnounceForm, CategoryForm, SubscriptionsImportForm, \ SendTestEmailForm, SendTestSMSForm from . import utils @@ -35,7 +35,7 @@ def login(request, *args, **kwargs): if 'next' not in request.GET: return HttpResponseRedirect(resolve_url('mellon_login')) return HttpResponseRedirect(resolve_url('mellon_login') + '?next=' + - urllib.quote(request.GET.get('next'))) + quote(request.GET.get('next'))) return auth_views.login(request, *args, **kwargs) diff --git a/debian/debian_config.py b/debian/debian_config.py index e99e9b6..dd1e689 100644 --- a/debian/debian_config.py +++ b/debian/debian_config.py @@ -1,4 +1,4 @@ -# This file is sourced by "execfile" from corbo.settings +# This file is sourced by "exec" from corbo.settings import os @@ -7,14 +7,14 @@ PROJECT_NAME = 'corbo' # # hobotization (multitenant) # -execfile('/usr/lib/hobo/debian_config_common.py') +exec(open('/usr/lib/hobo/debian_config_common.py').read()) INSTALLED_APPS = ('corbo.hobo_agent', ) + INSTALLED_APPS # # local settings # -execfile(os.path.join(ETC_DIR, 'settings.py')) +exec(open(os.path.join(ETC_DIR, 'settings.py')).read()) # run additional settings snippets -execfile('/usr/lib/hobo/debian_config_settings_d.py') +exec(open('/usr/lib/hobo/debian_config_settings_d.py').read()) diff --git a/debian/settings.py b/debian/settings.py index 17a39e8..f7116c6 100644 --- a/debian/settings.py +++ b/debian/settings.py @@ -9,7 +9,7 @@ # WARNING! Quick-start development settings unsuitable for production! # See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/ -# This file is sourced by "execfile" from /usr/lib/corbo/debian_config.py +# This file is sourced by "exec" from /usr/lib/corbo/debian_config.py # SECURITY WARNING: don't run with debug turned on in production! DEBUG = False diff --git a/setup.py b/setup.py index 0c6954c..70cb7f1 100644 --- a/setup.py +++ b/setup.py @@ -20,27 +20,39 @@ class eo_sdist(sdist): if os.path.exists('VERSION'): os.remove('VERSION') version = get_version() - version_file = open('VERSION', 'w') - version_file.write(version) - version_file.close() + with open('VERSION', 'w') as fd: + fd.write(version) sdist.run(self) if os.path.exists('VERSION'): os.remove('VERSION') + def get_version(): + '''Use the VERSION, if absent generates a version with git describe, if not + tag exists, take 0.0- and add the length of the commit log. + ''' if os.path.exists('VERSION'): - version_file = open('VERSION', 'r') - version = version_file.read() - version_file.close() - return version + with open('VERSION', 'r') as v: + return v.read() if os.path.exists('.git'): - p = subprocess.Popen(['git', 'describe', '--dirty', '--match=v*'], stdout=subprocess.PIPE) + p = subprocess.Popen( + ['git', 'describe', '--dirty=.dirty', '--match=v*'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) result = p.communicate()[0] if p.returncode == 0: - version = result.split()[0][1:] - version = version.replace('-', '.') + result = result.decode('ascii').strip()[1:] # strip spaces/newlines and initial v + if '-' in result: # not a tagged version + real_number, commit_count, commit_hash = result.split('-', 2) + version = '%s.post%s+%s' % (real_number, commit_count, commit_hash) + else: + version = result return version - return '0' + else: + return '0.0.post%s' % len(subprocess.check_output(['git', 'rev-list', 'HEAD']).splitlines()) + return '0.0' + class compile_translations(Command): description = 'compile message catalogs to MO files via django compilemessages' @@ -53,17 +65,20 @@ class compile_translations(Command): pass def run(self): + curdir = os.getcwd() try: from django.core.management import call_command + for path, dirs, files in os.walk('corbo'): if 'locale' not in dirs: continue - curdir = os.getcwd() os.chdir(os.path.realpath(path)) call_command('compilemessages') - os.chdir(curdir) except ImportError: sys.stderr.write('!!! Please install Django >= 1.4 to build translations\n') + finally: + os.chdir(curdir) + class build(_build): sub_commands = [('compile_translations', None)] + _build.sub_commands @@ -74,6 +89,7 @@ class install_lib(_install_lib): self.run_command('compile_translations') _install_lib.run(self) + setup( name='corbo', version=get_version(), @@ -110,5 +126,4 @@ setup( 'install_lib': install_lib, 'sdist': eo_sdist, }, - ) diff --git a/tests/test_announces.py b/tests/test_announces.py index f8692ba..c1a83d6 100644 --- a/tests/test_announces.py +++ b/tests/test_announces.py @@ -16,8 +16,7 @@ pytestmark = pytest.mark.django_db CATEGORIES = ('Alerts',) -ATOM_FEED = """ - +ATOM_FEED = """ tag:linuxfr.org,2005:/news Sample RSS Feeds @@ -54,10 +53,10 @@ def mocked_request_get(*args, **kwargs): return MockResponse(ATOM_FEED) elif args[0] == 'http://example.com/logo.png': logo_path = os.path.join(os.path.dirname(__file__), 'media', 'logo.png') - return MockResponse(file(logo_path).read()) + return MockResponse(open(logo_path, 'rb').read()) elif args[0] == 'http://example.com/folder/logo.png': logo_path = os.path.join(os.path.dirname(__file__), 'media', 'another_logo.png') - return MockResponse(file(logo_path).read()) + return MockResponse(open(logo_path, 'rb').read()) else: return MockResponse(None, ok=False) @@ -109,13 +108,13 @@ def test_announces_publishing(app): def test_rss_feed_items(app): c = Category.objects.create(name='Test announces') - for i in xrange(10): + for i in range(10): a = Announce.objects.create(category=c, title='Test %s' % i, publication_time=timezone.now(), text='text of announce %s' % i) feed_content = feedparser.parse(app.get(reverse('atom')).text) assert len(feed_content['entries']) <= settings.RSS_ITEMS_LIMIT - for i in xrange(i, 10): + for i in range(i, 10): a = Announce.objects.create(category=c, title='Test %s' % i, publication_time=timezone.now(), text='text of announce %s' % i) diff --git a/tests/test_api.py b/tests/test_api.py index a24a23f..e1c080c 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -146,14 +146,13 @@ def test_simple_email_subscription(app, categories, user): def test_simple_sms_subscription(app, categories, user, phonenumber): payload = {'category_id': 'alerts', 'transports': ['sms']} uuid = uuid4() - url_params = urllib.urlencode({'uuid': uuid, 'mobile': phonenumber}) + url_params = urlencode({'uuid': uuid, 'mobile': phonenumber}) url = '/api/subscribe/?' + url_params app.authorization = ('Basic', ('john.doe', 'password')) resp = app.post_json(url, params=payload, status=200) assert Subscription.objects.get(uuid=uuid).identifier in ['sms:0610203040', 'sms:+33610203040', 'sms:0033610203040'] resp = app.get('/api/subscriptions/?uuid=%s' % uuid) data = resp.json['data'] - print resp.json assert len(data) == 1 assert data[0]['id'] == 'alerts' assert data[0]['text'] == 'Alerts' diff --git a/tests/test_broadcasting.py b/tests/test_broadcasting.py index 5eda09d..d7db728 100644 --- a/tests/test_broadcasting.py +++ b/tests/test_broadcasting.py @@ -2,7 +2,6 @@ import pytest from uuid import uuid4 import os import re -import urllib import logging import mock import random @@ -12,6 +11,7 @@ from django.core.urlresolvers import reverse from django.core import mail, signing from django.utils import timezone from django.core.files.storage import DefaultStorage +from django.utils.six.moves.urllib import parse as urllib from django.utils.text import slugify from django.test import override_settings @@ -23,7 +23,7 @@ pytestmark = pytest.mark.django_db CATEGORIES = (u'Alerts', u'News') def get_random_number(): - number_generator = range(10) + number_generator = list(range(10)) random.shuffle(number_generator) number = ''.join(map(str, number_generator)) return number @@ -96,7 +96,7 @@ def test_check_inline_images(mocked_get, app, categories, announces, mailoutbox) storage = DefaultStorage() media_path = os.path.join(os.path.dirname(__file__), 'media') image_name = 'logo.png' - image_name = storage.save(image_name, file(os.path.join(media_path, image_name))) + image_name = storage.save(image_name, open(os.path.join(media_path, image_name), 'rb')) total_sent = 0 for i, announce in enumerate(announces): img_src = "/media/%s" % image_name @@ -126,7 +126,7 @@ def test_unsubscription_link(app, categories, announces, custom_mailoutbox): subscriptions_number = 3 scheme = 'mailto:' for category in categories: - for i in xrange(subscriptions_number): + for i in range(subscriptions_number): uuid = uuid4() uri = scheme + '%s@example.com' % uuid Subscription.objects.create(category=category, identifier=uri, uuid=str(uuid)) @@ -157,7 +157,7 @@ def test_unsubscription_link(app, categories, announces, custom_mailoutbox): # make sure the uri schema is not in the page resp = app.get(unsubscription_link) - assert scheme not in resp.content + assert scheme not in resp def test_send_sms_with_no_gateway_defined(app, categories, announces, caplog): for category in categories: diff --git a/tests/test_manager.py b/tests/test_manager.py index 24a3386..456049e 100644 --- a/tests/test_manager.py +++ b/tests/test_manager.py @@ -37,7 +37,7 @@ def test_unlogged_access(app): def test_access(app, admin_user): app = login(app) resp = app.get(reverse('manage'), status=200) - assert 'New category' in resp.body + assert 'New category' in resp def test_logout(app, admin_user): app = login(app) @@ -47,7 +47,7 @@ def test_logout(app, admin_user): def test_create_category(app, admin_user): app = login(app) resp = app.get(reverse('manage')) - assert 'New category' in resp.content + assert 'New category' in resp category_page = resp.click('New category') category_form = category_page.forms[0] category_form['name'] = 'Alerts' @@ -55,12 +55,12 @@ def test_create_category(app, admin_user): assert resp.status_int == 302 assert resp.location.endswith(reverse('manage')) resp = resp.follow() - assert 'Alerts' in resp.content + assert 'Alerts' in resp def test_edit_category(app, admin_user): app = login(app) resp = app.get(reverse('manage')) - assert 'New category' in resp.content + assert 'New category' in resp category_page = resp.click('New category') category_form = category_page.forms[0] category_form['name'] = 'Alerts' @@ -68,11 +68,11 @@ def test_edit_category(app, admin_user): assert resp.status_int == 302 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 + assert 'Alerts' in resp + assert '0 announces' in resp + assert '0 subscriptions' in resp resp = resp.click('Alerts') - assert 'Edit' in resp.content + assert 'Edit' in resp edit_page = resp.click('Edit') edit_form = edit_page.forms[0] edit_form['name'] = 'New Alerts' @@ -83,7 +83,7 @@ def test_edit_category(app, admin_user): def test_delete_category(app, admin_user): app = login(app) resp = app.get(reverse('manage')) - assert 'New category' in resp.content + assert 'New category' in resp category_page = resp.click('New category') category_form = category_page.forms[0] category_form['name'] = 'Alerts' @@ -91,11 +91,11 @@ def test_delete_category(app, admin_user): assert resp.status_int == 302 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 + assert 'Alerts' in resp + assert '0 announces' in resp + assert '0 subscriptions' in resp resp = resp.click('Alerts') - assert 'Delete' in resp.content + assert 'Delete' in resp delete_page = resp.click('Delete') delete_form = delete_page.forms[0] resp = delete_form.submit() @@ -105,7 +105,7 @@ def test_delete_category(app, admin_user): def test_create_announce(app, admin_user): app = login(app) resp = app.get('/manage/') - assert 'New category' in resp.content + assert 'New category' in resp category_page = resp.click('New category') category_form = category_page.forms[0] category_form['name'] = 'Alerts' @@ -113,9 +113,9 @@ def test_create_announce(app, admin_user): assert resp.status_int == 302 assert resp.location.endswith(reverse('manage')) resp = app.get(reverse('manage')) - assert 'Alerts' in resp.content + assert 'Alerts' in resp resp = resp.click('Alerts') - assert 'New announce' in resp.content + assert 'New announce' in resp announce_page = resp.click('New announce') announce_form = announce_page.forms[0] announce_form['title'] = 'First announce' @@ -125,12 +125,12 @@ def test_create_announce(app, admin_user): category_url = reverse('view_category', kwargs={'slug': 'alerts'}) assert resp.location.endswith(category_url) resp = resp.follow() - assert 'First announce' in resp.content + assert 'First announce' in resp def test_edit_announce(app, admin_user): app = login(app) resp = app.get('/manage/') - assert 'New category' in resp.content + assert 'New category' in resp category_page = resp.click('New category') category_form = category_page.forms[0] category_form['name'] = 'Alerts' @@ -139,7 +139,7 @@ def test_edit_announce(app, admin_user): assert resp.location.endswith(reverse('manage')) resp = app.get(resp.location) resp = resp.click('Alerts') - assert 'New announce' in resp.content + assert 'New announce' in resp announce_page = resp.click('New announce') announce_form = announce_page.forms[0] announce_form['title'] = 'First announce' @@ -148,12 +148,12 @@ def test_edit_announce(app, admin_user): assert resp.status_int == 302 assert resp.location.endswith(reverse('view_category', kwargs={'slug': 'alerts'})) resp = resp.follow() - assert 'First announce' in resp.content + assert 'First announce' in resp announce_page = resp.click('First announce') - assert 'First announce' in announce_page.content - assert 'Edit' in announce_page.content - assert 'Send test email' in announce_page.content - assert 'Delete' in announce_page.content + assert 'First announce' in announce_page + assert 'Edit' in announce_page + assert 'Send test email' in announce_page + assert 'Delete' in announce_page announce_edit_page = announce_page.click('Edit') edit_form = announce_edit_page.forms[0] edit_form['publication_time'] = '2017-03-03 09:00:00' @@ -170,23 +170,23 @@ def test_edit_announce(app, admin_user): resp = app.get(resp.location) - assert 'Publication March 3, 2017, 9 a.m.' in resp.content - assert 'Expiration Dec. 31, 2017, 11 p.m.' in resp.content - assert 'Sent March 30, 2017, 8 p.m.' in resp.content - assert 'to 1 destination' in resp.content + assert 'Publication March 3, 2017, 9 a.m.' in resp + assert 'Expiration Dec. 31, 2017, 11 p.m.' in resp + assert 'Sent March 30, 2017, 8 p.m.' in resp + assert 'to 1 destination' in resp broadcast.delivery_count = 2 broadcast.save() resp = app.get('http://testserver/manage/announce/1/') - assert 'Sent March 30, 2017, 8 p.m.' in resp.content - assert 'to 2 destinations' in resp.content + assert 'Sent March 30, 2017, 8 p.m.' in resp + assert 'to 2 destinations' in resp def test_delete_announce(app, admin_user): app = login(app) resp = app.get('/manage/') - assert 'New category' in resp.content + assert 'New category' in resp category_page = resp.click('New category') category_form = category_page.forms[0] category_form['name'] = 'Alerts' @@ -195,7 +195,7 @@ def test_delete_announce(app, admin_user): assert resp.location.endswith(reverse('manage')) resp = app.get(reverse('manage')) resp = resp.click('Alerts') - assert 'New announce' in resp.content + assert 'New announce' in resp announce_page = resp.click('New announce') announce_form = announce_page.forms[0] announce_form['title'] = 'First announce' @@ -204,10 +204,10 @@ def test_delete_announce(app, admin_user): assert resp.status_int == 302 assert resp.location.endswith(reverse('view_category', kwargs={'slug': 'alerts'})) resp = resp.follow() - assert 'First announce' in resp.content + assert 'First announce' in resp resp = resp.click('First announce') - assert 'Delete' in resp.content - assert 'Send test email' in resp.content + assert 'Delete' in resp + assert 'Send test email' in resp announce_delete_page = resp.click('Delete') announce_delete_form = announce_delete_page.forms[0] resp = announce_delete_form.submit() @@ -217,7 +217,7 @@ def test_delete_announce(app, admin_user): def test_email_announce(app, admin_user): app = login(app) resp = app.get('/manage/') - assert 'New category' in resp.content + assert 'New category' in resp category_page = resp.click('New category') category_form = category_page.forms[0] category_form['name'] = 'Alerts' @@ -226,7 +226,7 @@ def test_email_announce(app, admin_user): assert resp.location.endswith(reverse('manage')) resp = resp.follow() resp = resp.click('Alerts') - assert 'New announce' in resp.content + assert 'New announce' in resp announce_page = resp.click('New announce') announce_form = announce_page.forms[0] announce_form['title'] = 'First announce' @@ -235,17 +235,17 @@ def test_email_announce(app, admin_user): assert resp.status_int == 302 assert resp.location.endswith(reverse('view_category', kwargs={'slug': 'alerts'})) resp = resp.follow() - assert 'First announce' in resp.content + assert 'First announce' in resp resp = resp.click('First announce') - assert 'Send test email' in resp.content - assert 'Send test SMS' not in resp.content + assert 'Send test email' in resp + assert 'Send test SMS' not in resp resp = resp.click('Send test email') send_form = resp.forms[0] assert send_form.method == 'post' assert 'email' in send_form.fields assert send_form.fields['email'][0].value == admin_user.email - assert 'Send' in resp.content - assert 'Cancel' in resp.content + assert 'Send' in resp + assert 'Cancel' in resp resp = send_form.submit() assert resp.status_int == 302 assert resp.location.endswith(reverse('view_announce', kwargs={'pk': '1'})) @@ -254,7 +254,7 @@ def test_email_announce(app, admin_user): def test_sms_announce(mocked_post, app, admin_user, settings): app = login(app) resp = app.get('/manage/') - assert 'New category' in resp.content + assert 'New category' in resp category_page = resp.click('New category') category_form = category_page.forms[0] category_form['name'] = 'Alerts' @@ -265,7 +265,7 @@ def test_sms_announce(mocked_post, app, admin_user, settings): resp = resp.click('Alerts') # create new announce - assert 'New announce' in resp.content + assert 'New announce' in resp announce_page = resp.click('New announce') announce_form = announce_page.forms[0] announce_form['title'] = 'First announce' @@ -276,10 +276,10 @@ def test_sms_announce(mocked_post, app, admin_user, settings): resp = resp.follow() # view announce - assert 'First announce' in resp.content + assert 'First announce' in resp settings.SMS_GATEWAY_URL = 'http:/passerelle.com' resp = resp.click('First announce') - assert 'Send test SMS' in resp.content + assert 'Send test SMS' in resp # open send sms form resp = resp.click('Send test SMS') @@ -310,7 +310,7 @@ def test_sms_announce(mocked_post, app, admin_user, settings): assert resp.location.endswith(reverse('view_announce', kwargs={'pk': 1})) resp = resp.follow() # make sure the form informs about the success - assert 'SMS successfully sent' in resp.content + assert 'SMS successfully sent' in resp resp = resp.click('Send test SMS') form = resp.forms[0] @@ -319,19 +319,19 @@ def test_sms_announce(mocked_post, app, admin_user, settings): mocked_response.json.return_value = {'err': 1, 'data': None, 'err_desc': 'Destination error'} resp = form.submit() resp = resp.follow() - assert 'Error occured while sending SMS' in resp.content + assert 'Error occured while sending SMS' in resp def test_sms_announce_with_invalid_gateway_url(app, admin_user, settings, caplog): app = login(app) resp = app.get('/manage/') - assert 'New category' in resp.content + assert 'New category' in resp category_page = resp.click('New category') category_form = category_page.forms[0] category_form['name'] = 'Alerts' resp = category_form.submit() resp = resp.follow() resp = resp.click('Alerts') - assert 'New announce' in resp.content + assert 'New announce' in resp announce_page = resp.click('New announce') announce_form = announce_page.forms[0] announce_form['title'] = 'First announce' @@ -340,10 +340,10 @@ def test_sms_announce_with_invalid_gateway_url(app, admin_user, settings, caplog assert resp.status_int == 302 assert resp.location.endswith(reverse('view_category', kwargs={'slug': 'alerts'})) resp = resp.follow() - assert 'First announce' in resp.content + assert 'First announce' in resp settings.SMS_GATEWAY_URL='invalid_url' resp = resp.click('First announce') - assert 'Send test SMS' in resp.content + assert 'Send test SMS' in resp resp = resp.click('Send test SMS') form = resp.forms[0] form['mobile'] = '0607080900' diff --git a/tests/test_subscribers.py b/tests/test_subscribers.py index 5ba6d33..ee4f22b 100644 --- a/tests/test_subscribers.py +++ b/tests/test_subscribers.py @@ -1,3 +1,5 @@ +from __future__ import unicode_literals + import pytest from webtest import Upload @@ -46,7 +48,7 @@ def test_subscribe_from_csv(app, admin, categories): for c in categories: page = app.get(reverse('subscriptions-import', kwargs={'slug': c.slug})) form = page.form - form['subscribers'] = Upload('users.csv', CSV_CONTENT) + form['subscribers'] = Upload('users.csv', CSV_CONTENT.encode('utf-8')) res = form.submit() assert res.status_code == 302 assert Subscription.objects.filter(category=c).count() == len(CSV_CONTENT.splitlines()) @@ -57,7 +59,7 @@ def test_subscribe_from_csv_with_empty_lines(app, admin, categories): for c in categories: page = app.get(reverse('subscriptions-import', kwargs={'slug': c.slug})) form = page.form - form['subscribers'] = Upload('users.csv', content) + form['subscribers'] = Upload('users.csv', content.encode('utf-8')) res = form.submit() assert res.status_code == 302 assert Subscription.objects.filter(category=c).count() == len(CSV_CONTENT.splitlines()) @@ -68,7 +70,7 @@ def test_subscribe_with_invalid_email(app, admin, categories): for category in categories: page = app.get(reverse('subscriptions-import', kwargs={'slug': category.slug})) form = page.form - form['subscribers'] = Upload('users.csv', content) + form['subscribers'] = Upload('users.csv', content.encode('utf-8')) page = form.submit() assert page.status_code == 200 page.mustcontain('Invalid email address at line') diff --git a/tox.ini b/tox.ini index fe127fd..dd66cae 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,8 @@ [tox] -envlist = coverage-django111 +toxworkdir = {env:TMPDIR:/tmp}/tox-{env:USER}/corbo/{env:BRANCH_NAME:} +envlist = py2-coverage-django111,py3-django111 [testenv] -basepython = python2 usedevelop = coverage: True setenv =