From 1f9d1bfd8cdad32758b01c30a8588585ef264a5a Mon Sep 17 00:00:00 2001
From: Pierre-Yves Chibon <pingou@pingoured.fr>
Date: Dec 21 2018 14:23:41 +0000
Subject: [PATCH 1/3] Port fedocal to python3


Signed-off-by: Pierre-Yves Chibon <pingou@pingoured.fr>

---

diff --git a/fedocal/__init__.py b/fedocal/__init__.py
index 4bfc535..579bf01 100644
--- a/fedocal/__init__.py
+++ b/fedocal/__init__.py
@@ -22,10 +22,7 @@
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  MA 02110-1301, USA.
 """
-
-# These two lines are needed to run on EL6
-__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4']
-import pkg_resources
+from __future__ import unicode_literals, absolute_import, print_function
 
 __version__ = '0.16'
 
@@ -34,7 +31,6 @@ import logging
 import textwrap
 import os
 import urllib
-import urlparse
 from dateutil import parser
 from logging.handlers import SMTPHandler
 
@@ -42,14 +38,18 @@ import flask
 import bleach
 import jinja2
 import markdown
+import six
+import six.moves
 import vobject
 from dateutil.relativedelta import relativedelta
 from flask_fas_openid import FAS
 from flask_multistatic import MultiStaticFlask
 from functools import wraps
 from pytz import common_timezones
+from six.moves.urllib.parse import urlparse, urljoin
 from sqlalchemy.exc import SQLAlchemyError
 from werkzeug import secure_filename
+
 from fedocal.fedocal_babel import Babel
 from fedocal.fedocal_babel import gettext
 from fedocal.fedocal_babel import format_datetime
@@ -228,7 +228,7 @@ def format_time_spinner(time):
     """ Template filter returning for a given time only the hours and
     minutes.
     """
-    if isinstance(time, basestring):
+    if isinstance(time, six.string_types):
         return ':'.join(time.split(':')[:2])
     else:
         return time.strftime('%H:%M')
@@ -266,7 +266,7 @@ def is_admin():
         return False
 
     admins = APP.config['ADMIN_GROUP']
-    if isinstance(admins, basestring):
+    if isinstance(admins, six.string_types):
         admins = set([admins])
     else:  # pragma: no cover
         admins = set(admins)
@@ -337,7 +337,7 @@ def get_timezone():
 def chunks(item_list, chunks_size):
     """ Yield successive n-sized chunks from item_list.
     """
-    for i in xrange(0, len(item_list), chunks_size):
+    for i in six.moves.range(0, len(item_list), chunks_size):
         yield item_list[i: i + chunks_size]
 
 
@@ -345,9 +345,9 @@ def is_safe_url(target):
     """ Checks that the target url is safe and sending to the current
     website not some other malicious one.
     """
-    ref_url = urlparse.urlparse(flask.request.host_url)
-    test_url = urlparse.urlparse(
-        urlparse.urljoin(flask.request.host_url, target))
+    ref_url = urlparse(flask.request.host_url)
+    test_url = urlparse(
+        urljoin(flask.request.host_url, target))
     return test_url.scheme in ('http', 'https') and \
         ref_url.netloc == test_url.netloc
 
@@ -720,7 +720,7 @@ def auth_login():
         groups.update(cal.admin_groups)
         groups.update(cal.editor_groups)
 
-    if isinstance(APP.config['ADMIN_GROUP'], basestring):
+    if isinstance(APP.config['ADMIN_GROUP'], six.string_types):
         groups.update([APP.config['ADMIN_GROUP']])
     else:
         groups.update(APP.config['ADMIN_GROUP'])
@@ -1730,16 +1730,16 @@ def upload_calendar(calendar_name):
                       'file: "%s"',
                       flask.g.fas_user.username, ical_file.filename)
             LOG.exception(err)
-            flask.flash(err.message, 'error')
+            flask.flash("%s" % err, 'error')
             return flask.render_template(
                 'upload_calendar.html', form=form, calendar=calendarobj)
 
         try:
             fedocallib.add_vcal_file(
-                SESSION, calendarobj, ical_file, flask.g.fas_user, is_admin())
+                SESSION, calendarobj, ical_file.read(), flask.g.fas_user, is_admin())
             flask.flash(gettext('Calendar uploaded'))
         except FedocalException as err:  # pragma: no cover
-            flask.flash(err.message, 'error')
+            flask.flash("%s" % err, 'error')
             return flask.render_template(
                 'upload_calendar.html', form=form, calendar=calendarobj)
         except SQLAlchemyError as err:  # pragma: no cover
diff --git a/fedocal/api.py b/fedocal/api.py
index ea68f61..eeaf65f 100644
--- a/fedocal/api.py
+++ b/fedocal/api.py
@@ -22,18 +22,18 @@
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  MA 02110-1301, USA.
 """
+from __future__ import unicode_literals, absolute_import, print_function
 
 
 import datetime
-import flask
 import json
-
 from dateutil import parser
+
+import flask
 from sqlalchemy.exc import SQLAlchemyError
 
 import fedocal.fedocallib as fedocallib
 from fedocal.doc_utils import load_doc
-
 from fedocal import APP, SESSION, LOG
 from fedocal.fedocallib.model import Calendar
 
diff --git a/fedocal/default_config.py b/fedocal/default_config.py
index c0d9a09..eaea502 100644
--- a/fedocal/default_config.py
+++ b/fedocal/default_config.py
@@ -22,6 +22,7 @@
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  MA 02110-1301, USA.
 """
+from __future__ import unicode_literals, absolute_import
 
 import os
 
diff --git a/fedocal/doc_utils.py b/fedocal/doc_utils.py
index 3df72df..b4976a3 100644
--- a/fedocal/doc_utils.py
+++ b/fedocal/doc_utils.py
@@ -23,9 +23,12 @@
  MA 02110-1301, USA.
 """
 
+from __future__ import unicode_literals, absolute_import
+
 import docutils
 import docutils.examples
 import markupsafe
+import six
 
 
 def modify_rst(rst):
@@ -72,7 +75,9 @@ def modify_html(html):
 def load_doc(endpoint):
     """ Utility to load an RST file and turn it into fancy HTML. """
 
-    rst = unicode(endpoint.__doc__)
+    rst = endpoint.__doc__
+    if isinstance(rst, six.binary_type):
+        rst = rst.decode('utf-8')
 
     rst = modify_rst(rst)
 
diff --git a/fedocal/fedocal_babel.py b/fedocal/fedocal_babel.py
index 6c90380..3303464 100644
--- a/fedocal/fedocal_babel.py
+++ b/fedocal/fedocal_babel.py
@@ -24,6 +24,7 @@
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  MA 02110-1301, USA.
 """
+from __future__ import unicode_literals, absolute_import, print_function
 
 from babel import support
 
diff --git a/fedocal/fedocallib/__init__.py b/fedocal/fedocallib/__init__.py
index e28aae3..9f4f703 100644
--- a/fedocal/fedocallib/__init__.py
+++ b/fedocal/fedocallib/__init__.py
@@ -13,12 +13,10 @@ your option) any later version.
 See http://www.gnu.org/copyleft/gpl.html  for the full text of the
 license.
 """
+from __future__ import unicode_literals, absolute_import, print_function
 
 import copy
-import vobject
-import pytz
 import operator
-
 from datetime import datetime
 from datetime import date
 from datetime import time
@@ -27,6 +25,9 @@ from dateutil import zoneinfo
 from dateutil.relativedelta import relativedelta
 import dateutil.rrule as rrule
 
+import six
+import pytz
+import vobject
 from sqlalchemy import create_engine
 from sqlalchemy.exc import SQLAlchemyError
 from sqlalchemy.orm import sessionmaker
@@ -1183,6 +1184,9 @@ def add_vcal_file(session, calendar, stream, fas_user, admin=False):
         'EDT': 'US/Eastern',
     }
 
+    if isinstance(stream, six.binary_type):
+        stream = stream.decode('utf-8')
+
     meetings = vobject.readOne(stream)
     for meeting in meetings.components():
         if meeting.name == 'VTIMEZONE':
diff --git a/fedocal/fedocallib/dbaction.py b/fedocal/fedocallib/dbaction.py
index 931e7c9..0f73957 100644
--- a/fedocal/fedocallib/dbaction.py
+++ b/fedocal/fedocallib/dbaction.py
@@ -14,6 +14,7 @@ your option) any later version.
 See http://www.gnu.org/copyleft/gpl.html  for the full text of the
 license.
 """
+from __future__ import unicode_literals, absolute_import, print_function
 
 from datetime import date
 from fedocal.fedocallib import  model
diff --git a/fedocal/fedocallib/exceptions.py b/fedocal/fedocallib/exceptions.py
index d8cb0b6..fd6f962 100644
--- a/fedocal/fedocallib/exceptions.py
+++ b/fedocal/fedocallib/exceptions.py
@@ -13,6 +13,7 @@ your option) any later version.
 See http://www.gnu.org/copyleft/gpl.html  for the full text of the
 license.
 """
+from __future__ import unicode_literals, absolute_import, print_function
 
 
 # pylint: disable=R0903
diff --git a/fedocal/fedocallib/fedmsgshim.py b/fedocal/fedocallib/fedmsgshim.py
index 139765e..9729095 100644
--- a/fedocal/fedocallib/fedmsgshim.py
+++ b/fedocal/fedocallib/fedmsgshim.py
@@ -5,6 +5,7 @@ messages.  If it is not installed, it will return silently.
   :Author: Ralph Bean <rbean@redhat.com>
 
 """
+from __future__ import unicode_literals, absolute_import, print_function
 
 import warnings
 
diff --git a/fedocal/fedocallib/fedora_calendar.py b/fedocal/fedocallib/fedora_calendar.py
index e32a041..391f3b0 100644
--- a/fedocal/fedocallib/fedora_calendar.py
+++ b/fedocal/fedocallib/fedora_calendar.py
@@ -14,17 +14,22 @@ your option) any later version.
 See http://www.gnu.org/copyleft/gpl.html  for the full text of the
 license.
 """
+from __future__ import unicode_literals, absolute_import, print_function
 
-from datetime import date
-from calendar import LocaleHTMLCalendar
-from calendar import TimeEncoding
-from calendar import month_name
+import calendar
 import locale
-import fedocal
+from datetime import date
+try:
+    from calendar import TimeEncoding
+    PY3 = False
+except ImportError:
+    PY3 = True
+
 import flask
 
+import fedocal
 
-class FedocalCalendar(LocaleHTMLCalendar):
+class FedocalCalendar(calendar.LocaleHTMLCalendar):
     """ Improve Python's HTMLCalendar object adding
     html validation and some features 'locally required'
     """
@@ -112,15 +117,19 @@ class FedocalCalendar(LocaleHTMLCalendar):
         if self.locale in ['en', 'en_EN']:
             lcle = 'C'
 
-        with TimeEncoding(lcle) as encoding:
-            smonth = month_name[themonth]
-            if encoding is not None:
-                smonth = smonth.decode(encoding)
+        if PY3:
+            with calendar.different_locale(lcle) as encoding:
+                smonth = calendar.month_name[themonth].capitalize()
+        else:
+            with TimeEncoding(lcle) as encoding:
+                smonth = calendar.month_name[themonth].capitalize()
+                if encoding is not None:
+                    smonth = smonth.decode(encoding).capitalize()
 
-            if withyear:
-                string = '%s %s' % (smonth, theyear)
-            else:
-                string = '%s' % smonth
+        if withyear:
+            string = '%s %s' % (smonth, theyear)
+        else:
+            string = '%s' % smonth
 
         prev_month = self.month - 1
         prev_year = self.year
diff --git a/fedocal/fedocallib/model.py b/fedocal/fedocallib/model.py
index 73fda81..408666d 100644
--- a/fedocal/fedocallib/model.py
+++ b/fedocal/fedocallib/model.py
@@ -14,13 +14,14 @@ your option) any later version.
 See http://www.gnu.org/copyleft/gpl.html  for the full text of the
 license.
 """
-__requires__ = ['SQLAlchemy >= 0.7']
-import pkg_resources
+from __future__ import unicode_literals, absolute_import, print_function
+
 import operator
 
 from datetime import date
 from datetime import timedelta
 
+import six
 from sqlalchemy import (
     Boolean,
     create_engine,
@@ -411,7 +412,7 @@ class Meeting(BASE):
         if ',' in meeting_manager:
             meeting_manager = meeting_manager.split(',')
 
-        if isinstance(meeting_manager, basestring):
+        if isinstance(meeting_manager, six.string_types):
             meeting_manager = [meeting_manager]
 
         for manager in meeting_manager:
diff --git a/fedocal/fedocallib/week.py b/fedocal/fedocallib/week.py
index 27b06c4..80e8d0d 100644
--- a/fedocal/fedocallib/week.py
+++ b/fedocal/fedocallib/week.py
@@ -13,6 +13,7 @@ your option) any later version.
 See http://www.gnu.org/copyleft/gpl.html  for the full text of the
 license.
 """
+from __future__ import unicode_literals, absolute_import, print_function
 
 from datetime import timedelta
 import operator
diff --git a/fedocal/flask_multistatic.py b/fedocal/flask_multistatic.py
index 525e425..91254c0 100644
--- a/fedocal/flask_multistatic.py
+++ b/fedocal/flask_multistatic.py
@@ -23,6 +23,7 @@
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  MA 02110-1301, USA.
 """
+from __future__ import unicode_literals, absolute_import, print_function
 
 import os
 import sys
diff --git a/fedocal/i18nforms.py b/fedocal/i18nforms.py
index 03794d8..d52ef84 100644
--- a/fedocal/i18nforms.py
+++ b/fedocal/i18nforms.py
@@ -23,6 +23,7 @@
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  MA 02110-1301, USA.
 """
+from __future__ import unicode_literals, absolute_import, print_function
 
 try:
    from flask_wtf import FlaskForm as FlaskForm
diff --git a/fedocal/mail_logging.py b/fedocal/mail_logging.py
index b162291..d243373 100644
--- a/fedocal/mail_logging.py
+++ b/fedocal/mail_logging.py
@@ -18,6 +18,7 @@
 # License and may only be used or replicated with the express permission
 # of Red Hat, Inc.
 #
+from __future__ import unicode_literals, absolute_import, print_function
 
 '''
 Mail handler for logging.
diff --git a/fedocal/proxy.py b/fedocal/proxy.py
index 33a1daa..89bc75d 100644
--- a/fedocal/proxy.py
+++ b/fedocal/proxy.py
@@ -18,6 +18,7 @@
 # License and may only be used or replicated with the express permission
 # of Red Hat, Inc.
 #
+from __future__ import unicode_literals, absolute_import, print_function
 
 '''
 Makes fedocal an application behind a reverse proxy and thus ensure the
diff --git a/tests/__init__.py b/tests/__init__.py
index 90ad14d..61d3089 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -26,20 +26,18 @@
 
  fedocal.model test script
 """
-from __future__ import print_function
-
-__requires__ = ['SQLAlchemy >= 0.7']
-import pkg_resources
+from __future__ import unicode_literals, absolute_import, print_function
 
 import unittest
 import sys
 import os
 
+from contextlib import contextmanager
 from datetime import date
 from datetime import timedelta
 from functools import wraps
 
-from contextlib import contextmanager
+import six
 from sqlalchemy import create_engine
 from sqlalchemy.orm import sessionmaker
 from sqlalchemy.orm import scoped_session
@@ -152,7 +150,7 @@ class FakeUser(object):
         :arg groups: list of the groups in which this fake user is
             supposed to be.
         """
-        if isinstance(groups, basestring):
+        if isinstance(groups, six.string_types):
             groups = [groups]
         self.groups = groups
         self.username = username
diff --git a/tests/test_calendar.py b/tests/test_calendar.py
index 204d18c..f7197c5 100644
--- a/tests/test_calendar.py
+++ b/tests/test_calendar.py
@@ -26,9 +26,7 @@
 
  fedocal.model test script
 """
-
-__requires__ = ['SQLAlchemy >= 0.7']
-import pkg_resources
+from __future__ import unicode_literals, absolute_import, print_function
 
 import unittest
 import sys
diff --git a/tests/test_cron.py b/tests/test_cron.py
index 059f2af..1c29df1 100644
--- a/tests/test_cron.py
+++ b/tests/test_cron.py
@@ -27,8 +27,7 @@
  tests for fedocal's cron job
 """
 
-__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4']
-import pkg_resources
+from __future__ import unicode_literals, absolute_import, print_function
 
 import logging
 import unittest
@@ -49,8 +48,8 @@ from fedocal.fedocallib import week
 from fedocal.fedocallib import exceptions
 
 import tests
-from tests import Modeltests
-from test_meeting import Meetingtests, TODAY
+from . import Modeltests
+from .test_meeting import Meetingtests, TODAY
 
 
 DB_PATH = 'sqlite:////tmp/fedocal_test.sqlite'
diff --git a/tests/test_fedocallib.py b/tests/test_fedocallib.py
index 97229a6..d0001f4 100644
--- a/tests/test_fedocallib.py
+++ b/tests/test_fedocallib.py
@@ -26,9 +26,7 @@
 
  fedocal.model test script
 """
-
-__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4']
-import pkg_resources
+from __future__ import unicode_literals, absolute_import, print_function
 
 import unittest
 import sys
@@ -62,7 +60,7 @@ class Fedocallibtests(Modeltests):
 
     def __setup_calendar(self):
         """ Set up basic calendar information. """
-        from test_calendar import Calendartests
+        from .test_calendar import Calendartests
         cal = Calendartests('test_init_calendar')
         cal.session = self.session
         cal.test_init_calendar()
@@ -70,7 +68,7 @@ class Fedocallibtests(Modeltests):
     def __setup_meeting(self):
         """ Set up basic calendar information and add some meetings in
         them. """
-        from test_meeting import Meetingtests
+        from .test_meeting import Meetingtests
         meeting = Meetingtests('test_init_meeting')
         meeting.session = self.session
         meeting.test_init_meeting()
diff --git a/tests/test_fedocallib_extras.py b/tests/test_fedocallib_extras.py
index 04f93f0..9c376cb 100644
--- a/tests/test_fedocallib_extras.py
+++ b/tests/test_fedocallib_extras.py
@@ -27,9 +27,7 @@
  fedocal.lib tests script
  - for special corner case to test
 """
-
-__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4']
-import pkg_resources
+from __future__ import unicode_literals, absolute_import, print_function
 
 import unittest
 import sys
diff --git a/tests/test_fedora_calendar.py b/tests/test_fedora_calendar.py
index 74951f0..aa10e5c 100644
--- a/tests/test_fedora_calendar.py
+++ b/tests/test_fedora_calendar.py
@@ -26,9 +26,7 @@
 
  fedocal.model test script
 """
-
-__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4']
-import pkg_resources
+from __future__ import unicode_literals, absolute_import, print_function
 
 import unittest
 import sys
diff --git a/tests/test_flask.py b/tests/test_flask.py
index 38cb7d7..264c9cb 100644
--- a/tests/test_flask.py
+++ b/tests/test_flask.py
@@ -26,12 +26,11 @@
 
  fedocal.model test script
 """
-from __future__ import print_function
+from __future__ import unicode_literals, absolute_import, print_function
 
 __requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4']
 import pkg_resources
 
-import flask
 import logging
 import unittest
 import sys
@@ -43,6 +42,9 @@ from datetime import datetime
 from datetime import time
 from datetime import timedelta
 
+import flask
+import six
+
 sys.path.insert(0, os.path.join(os.path.dirname(
     os.path.abspath(__file__)), '..'))
 
@@ -57,10 +59,12 @@ from tests import (Modeltests, FakeUser, flask10_only, user_set, TODAY,
 class Flasktests(Modeltests):
     """ Flask application tests. """
 
+    maxDiff = None
+
     def __setup_db(self):
         """ Add a calendar and some meetings so that we can play with
         something. """
-        from test_meeting import Meetingtests
+        from .test_meeting import Meetingtests
         meeting = Meetingtests('test_init_meeting')
         meeting.session = self.session
         meeting.test_init_meeting()
@@ -73,14 +77,12 @@ class Flasktests(Modeltests):
         :arg filename: A string
         :returns: A string
         """
-        f = open(
-            os.path.join(
-                os.path.dirname(__file__),
-                'sample_files/{}'.format(filename)
-            )
+        filename = os.path.join(
+            os.path.dirname(__file__),
+            'sample_files/{}'.format(filename)
         )
-        content = f.read()
-        f.close()
+        with open(filename) as stream:
+            content = stream.read()
         return content
 
     def wrap_content(self, content, replacements=[]):
@@ -112,8 +114,9 @@ class Flasktests(Modeltests):
         """ Test the index function. """
         output = self.app.get('/')
         self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
         self.assertTrue(
-            '<title>Home - Fedocal</title>' in output.data)
+            '<title>Home - Fedocal</title>', output_text)
 
     def test_index(self):
         """ Test the index function. """
@@ -121,11 +124,12 @@ class Flasktests(Modeltests):
 
         output = self.app.get('/')
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>Home - Fedocal</title>' in output.data)
-        self.assertTrue('href="/test_calendar/">' in output.data)
-        self.assertTrue('href="/test_calendar2/">' in output.data)
-        self.assertTrue('href="/test_calendar4/">' in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>Home - Fedocal</title>', output_text)
+        self.assertIn('href="/test_calendar/">', output_text)
+        self.assertIn('href="/test_calendar2/">', output_text)
+        self.assertIn('href="/test_calendar4/">', output_text)
 
     def test_calendar(self):
         """ Test the calendar function. """
@@ -136,31 +140,35 @@ class Flasktests(Modeltests):
 
         output = self.app.get('/test_calendar', follow_redirects=True)
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>test_calendar - Fedocal</title>' in output.data)
-        self.assertTrue(' <a href="/test_calendar/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar2/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar4/">' in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
+        self.assertIn(' <a href="/test_calendar/">', output_text)
+        self.assertIn(' <a href="/test_calendar2/">', output_text)
+        self.assertIn(' <a href="/test_calendar4/">', output_text)
 
         output = self.app.get('/test_calendar2/')
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>test_calendar2 - Fedocal</title>' in output.data)
-        self.assertTrue(' <a href="/test_calendar/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar2/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar4/">' in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>test_calendar2 - Fedocal</title>', output_text)
+        self.assertIn(' <a href="/test_calendar/">', output_text)
+        self.assertIn(' <a href="/test_calendar2/">', output_text)
+        self.assertIn(' <a href="/test_calendar4/">', output_text)
 
         output = self.app.get('/foorbar/', follow_redirects=True)
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            'class="errors">No calendar named foorbar could be found</'
-            in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            'class="errors">No calendar named foorbar could be found</',
+            output_text)
 
         output = self.app.get('/test_calendar2/?tzone=Europe/Paris',
                               follow_redirects=True)
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>test_calendar2 - Fedocal</title>' in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>test_calendar2 - Fedocal</title>', output_text)
 
     def test_location(self):
         """ Test the location calendar function. """
@@ -171,11 +179,12 @@ class Flasktests(Modeltests):
 
         output = self.app.get('/location/test/', follow_redirects=True)
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>test - Fedocal</title>' in output.data)
-        self.assertTrue(' <a href="/test_calendar/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar2/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar4/">' in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>test - Fedocal</title>', output_text)
+        self.assertIn(' <a href="/test_calendar/">', output_text)
+        self.assertIn(' <a href="/test_calendar2/">', output_text)
+        self.assertIn(' <a href="/test_calendar4/">', output_text)
 
     def test_calendar_fullday(self):
         """ Test the calendar_fullday function. """
@@ -186,11 +195,12 @@ class Flasktests(Modeltests):
             '/test_calendar/%s/%s/%s/' % (
                 today.year, today.month, today.day))
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>test_calendar - Fedocal</title>' in output.data)
-        self.assertTrue(' <a href="/test_calendar/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar2/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar4/">' in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
+        self.assertIn(' <a href="/test_calendar/">', output_text)
+        self.assertIn(' <a href="/test_calendar2/">', output_text)
+        self.assertIn(' <a href="/test_calendar4/">', output_text)
 
         output = self.app.get(
             '/test_calendar/%s/%s/%s' % (
@@ -200,11 +210,12 @@ class Flasktests(Modeltests):
         output = self.app.get('/test_calendar/%s/%s/%s/' % (
             today.year, today.month, today.day), follow_redirects=True)
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>test_calendar - Fedocal</title>' in output.data)
-        self.assertTrue(' <a href="/test_calendar/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar2/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar4/">' in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
+        self.assertIn(' <a href="/test_calendar/">', output_text)
+        self.assertIn(' <a href="/test_calendar2/">', output_text)
+        self.assertIn(' <a href="/test_calendar4/">', output_text)
 
     def test_calendar_list(self):
         """ Test the calendar_list function. """
@@ -212,27 +223,30 @@ class Flasktests(Modeltests):
 
         output = self.app.get('/list/test_calendar/')
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>test_calendar - Fedocal</title>' in output.data)
-        self.assertTrue(' <a href="/test_calendar/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar2/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar4/">' in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
+        self.assertIn(' <a href="/test_calendar/">', output_text)
+        self.assertIn(' <a href="/test_calendar2/">', output_text)
+        self.assertIn(' <a href="/test_calendar4/">', output_text)
 
         output = self.app.get('/list/foorbar/', follow_redirects=True)
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            'class="errors">No calendar named foorbar could be found</'
-            in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            'class="errors">No calendar named foorbar could be found</',
+            output_text)
 
         today = date.today()
         output = self.app.get('/list/test_calendar/%s/%s/%s/' % (
             today.year, today.month, today.day))
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>test_calendar - Fedocal</title>' in output.data)
-        self.assertTrue(' <a href="/test_calendar/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar2/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar4/">' in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
+        self.assertIn(' <a href="/test_calendar/">', output_text)
+        self.assertIn(' <a href="/test_calendar2/">', output_text)
+        self.assertIn(' <a href="/test_calendar4/">', output_text)
 
         output = self.app.get('/list/test_calendar/%s/%s/%s' % (
             today.year, today.month, today.day))
@@ -241,69 +255,74 @@ class Flasktests(Modeltests):
         output = self.app.get('/list/test_calendar/%s/%s/%s/' % (
             today.year, today.month, today.day), follow_redirects=True)
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>test_calendar - Fedocal</title>' in output.data)
-        self.assertTrue(' <a href="/test_calendar/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar2/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar4/">' in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
+        self.assertIn(' <a href="/test_calendar/">', output_text)
+        self.assertIn(' <a href="/test_calendar2/">', output_text)
+        self.assertIn(' <a href="/test_calendar4/">', output_text)
 
         output = self.app.get('/list/test_calendar/%s/%s/' % (
             today.year, today.month), follow_redirects=True)
         self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
         # 6 on Tue Jun 24 - 12 before, 14 on Tue Jul 15
-        self.assertTrue(output.data.count('<a class="event meeting_') >= 5)
-        self.assertTrue(output.data.count('<tr') > 10)
-        self.assertTrue(
-            '<title>test_calendar - Fedocal</title>' in output.data)
-        self.assertTrue(' <a href="/test_calendar/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar2/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar4/">' in output.data)
+        self.assertTrue(output_text.count('<a class="event meeting_') >= 5)
+        self.assertTrue(output_text.count('<tr') > 10)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
+        self.assertIn(' <a href="/test_calendar/">', output_text)
+        self.assertIn(' <a href="/test_calendar2/">', output_text)
+        self.assertIn(' <a href="/test_calendar4/">', output_text)
 
         output = self.app.get('/list/test_calendar/%s/%s/?subject=Another'
             % (today.year, today.month), follow_redirects=True)
         self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
         # 4 on Tue Jun 24 - 6 before, 8 on Tue Jul 15
-        self.assertTrue(output.data.count('<a class="event meeting_') >= 4)
-        self.assertTrue(output.data.count('<tr') > 10)
-        self.assertTrue(
-            '<title>test_calendar - Fedocal</title>' in output.data)
-        self.assertTrue(' <a href="/test_calendar/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar2/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar4/">' in output.data)
+        self.assertTrue(output_text.count('<a class="event meeting_') >= 4)
+        self.assertTrue(output_text.count('<tr') > 10)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
+        self.assertIn(' <a href="/test_calendar/">', output_text)
+        self.assertIn(' <a href="/test_calendar2/">', output_text)
+        self.assertIn(' <a href="/test_calendar4/">', output_text)
 
         output = self.app.get('/list/test_calendar/%s/%s/?subject=Another past'
             % (today.year, today.month), follow_redirects=True)
         self.assertEqual(output.status_code, 200)
-        self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
         # 3 on Tue Jun 24 - 4 before, 5 on Tue Jul 15
-        self.assertTrue(output.data.count('<a class="event meeting_') >= 3)
-        self.assertTrue(output.data.count('<tr') >= 10)
-        self.assertTrue(
-            '<title>test_calendar - Fedocal</title>' in output.data)
-        self.assertTrue(' <a href="/test_calendar/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar2/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar4/">' in output.data)
+        self.assertTrue(output_text.count('<a class="event meeting_') >= 3)
+        self.assertTrue(output_text.count('<tr') >= 10)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
+        self.assertIn(' <a href="/test_calendar/">', output_text)
+        self.assertIn(' <a href="/test_calendar2/">', output_text)
+        self.assertIn(' <a href="/test_calendar4/">', output_text)
 
         output = self.app.get('/list/test_calendar/%s/%s/?delta=10'
             % (today.year, today.month), follow_redirects=True)
         self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
         # 1 on Tue Jun 24 - 2 before
         self.assertTrue(
-            output.data.count(
+            output_text.count(
                 '<a class="event event_blue meeting_') in range(9))
-        self.assertTrue(output.data.count('<tr') >= 6)
-        self.assertTrue(
-            '<title>test_calendar - Fedocal</title>' in output.data)
+        self.assertTrue(output_text.count('<tr') >= 6)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
 
         output = self.app.get('/list/test_calendar/%s/%s/?delta=abc'
             % (today.year, today.month), follow_redirects=True)
         self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
         # 6 on Tue Jun 24 - 12 before, 14 on Tue Jul 15
-        self.assertTrue(output.data.count(
+        self.assertTrue(output_text.count(
             '<a class="event event_blue meeting_') >= 5)
-        self.assertTrue(output.data.count('<tr') >= 10)
-        self.assertTrue(
-            '<title>test_calendar - Fedocal</title>' in output.data)
+        self.assertTrue(output_text.count('<tr') >= 10)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
 
         end_date = today + timedelta(days=10)
 
@@ -311,24 +330,26 @@ class Flasktests(Modeltests):
             % (today.year, today.month, end_date.strftime('%Y-%m')
             ), follow_redirects=True)
         self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
         # 14 on Tue Jun 24 - 2 before, 1 on August 15th
-        self.assertTrue(output.data.count(
+        self.assertTrue(output_text.count(
             '<a class="event event_blue meeting_') > 0)
         # 22 on Tue Jun 24 - 10 before, 8 on August 15th
-        self.assertTrue(output.data.count('<tr') >= 7)
-        self.assertTrue(
-            '<title>test_calendar - Fedocal</title>' in output.data)
+        self.assertTrue(output_text.count('<tr') >= 7)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
 
         output = self.app.get('/list/test_calendar/%s/%s/?end=foobar'
             % (today.year, today.month), follow_redirects=True)
         self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
         # 6 on Tue Jun 24 - 12 before, 14 on Tue Jul 15
-        self.assertTrue(output.data.count('<a class="event meeting_') >= 5)
+        self.assertTrue(output_text.count('<a class="event meeting_') >= 5)
         # 14 on Tue Jun 24 - 20 before, 21 on Tue Jul 15, 27 on Fri Aug 1
         # 22 on August 15th
-        self.assertTrue(output.data.count('<tr') >= 12)
-        self.assertTrue(
-            '<title>test_calendar - Fedocal</title>' in output.data)
+        self.assertTrue(output_text.count('<tr') >= 12)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
 
     def test_ical_out(self):
         """ Test the ical_out function. """
@@ -336,14 +357,15 @@ class Flasktests(Modeltests):
 
         output = self.app.get('/ical/test_calendar/')
         self.assertEqual(output.status_code, 200)
-        self.assertTrue('BEGIN:VCALENDAR' in output.data)
-        self.assertTrue('SUMMARY:test-meeting2' in output.data)
-        self.assertTrue(
-            'DESCRIPTION:This is a test meeting with recursion'
-            in output.data)
-        self.assertTrue('ORGANIZER:pingou' in output.data)
-        self.assertEqual(output.data.count('BEGIN:VEVENT'), 10)
-        self.assertEqual(output.data.count('END:VEVENT'), 10)
+        output_text = output.get_data(as_text=True)
+        self.assertIn('BEGIN:VCALENDAR', output_text)
+        self.assertIn('SUMMARY:test-meeting2', output_text)
+        self.assertIn(
+            'DESCRIPTION:This is a test meeting with recursion',
+            output_text)
+        self.assertIn('ORGANIZER:pingou', output_text)
+        self.assertEqual(output_text.count('BEGIN:VEVENT'), 10)
+        self.assertEqual(output_text.count('END:VEVENT'), 10)
 
         output = self.app.get('/ical/foorbar/')
         self.assertEqual(output.status_code, 404)
@@ -354,44 +376,48 @@ class Flasktests(Modeltests):
 
         output = self.app.get('/location/list/EMEA/')
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title> EMEA  - Fedocal</title>' in output.data)
-        self.assertTrue(' <a href="/test_calendar/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar2/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar4/">' in output.data)
-        self.assertEqual(output.data.count('<a class="event event_blue'), 2)
-        self.assertEqual(output.data.count('<a class="event'), 4)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title> EMEA  - Fedocal</title>', output_text)
+        self.assertIn(' <a href="/test_calendar/">', output_text)
+        self.assertIn(' <a href="/test_calendar2/">', output_text)
+        self.assertIn(' <a href="/test_calendar4/">', output_text)
+        self.assertEqual(output_text.count('<a class="event event_blue'), 1)
+        self.assertEqual(output_text.count('<a class="event'), 2)
 
         output = self.app.get('/location/list/foorbar/', follow_redirects=True)
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            'class="errors">No location named foorbar could be found</'
-            in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            'class="errors">No location named foorbar could be found</',
+            output_text)
 
         today = date.today()
         output = self.app.get('/location/list/EMEA/%s/%s/%s/' % (
             today.year, today.month, today.day))
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title> EMEA  - Fedocal</title>' in output.data)
-        self.assertTrue(' <a href="/test_calendar/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar2/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar4/">' in output.data)
-        self.assertTrue(
-            output.data.count('<a class="event event_blue') in [0, 1])
-        self.assertTrue(output.data.count('<a class="event') in range(3))
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title> EMEA  - Fedocal</title>', output_text)
+        self.assertIn(' <a href="/test_calendar/">', output_text)
+        self.assertIn(' <a href="/test_calendar2/">', output_text)
+        self.assertIn(' <a href="/test_calendar4/">', output_text)
+        self.assertIn(
+            output_text.count('<a class="event event_blue'), [0, 1])
+        self.assertIn(output_text.count('<a class="event'), range(3))
 
         output = self.app.get('/location/list/EMEA/%s/%s/' % (
             today.year, today.month))
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title> EMEA  - Fedocal</title>' in output.data)
-        self.assertTrue(' <a href="/test_calendar/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar2/">' in output.data)
-        self.assertTrue(' <a href="/test_calendar4/">' in output.data)
-        self.assertTrue(
-            output.data.count('<a class="event event_blue') in [1, 2])
-        self.assertTrue(output.data.count('<a class="event') in [2, 4])
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title> EMEA  - Fedocal</title>', output_text)
+        self.assertIn(' <a href="/test_calendar/">', output_text)
+        self.assertIn(' <a href="/test_calendar2/">', output_text)
+        self.assertIn(' <a href="/test_calendar4/">', output_text)
+        self.assertIn(
+            output_text.count('<a class="event event_blue'), [1, 2])
+        self.assertIn(output_text.count('<a class="event'), [2, 4])
 
     def test_ical_all(self):
         """ Test the ical_all function. """
@@ -399,14 +425,15 @@ class Flasktests(Modeltests):
 
         output = self.app.get('/ical/')
         self.assertEqual(output.status_code, 200)
-        self.assertTrue('BEGIN:VCALENDAR' in output.data)
-        self.assertTrue('SUMMARY:test-meeting2' in output.data)
-        self.assertTrue(
-            'DESCRIPTION:This is a test meeting with recursion'
-            in output.data)
-        self.assertTrue('ORGANIZER:pingou' in output.data)
-        self.assertEqual(output.data.count('BEGIN:VEVENT'), 15)
-        self.assertEqual(output.data.count('END:VEVENT'), 15)
+        output_text = output.get_data(as_text=True)
+        self.assertIn('BEGIN:VCALENDAR', output_text)
+        self.assertIn('SUMMARY:test-meeting2', output_text)
+        self.assertIn(
+            'DESCRIPTION:This is a test meeting with recursion',
+            output_text)
+        self.assertIn('ORGANIZER:pingou', output_text)
+        self.assertEqual(output_text.count('BEGIN:VEVENT'), 15)
+        self.assertEqual(output_text.count('END:VEVENT'), 15)
 
     def test_ical_meeting(self):
         """ Test the ical_calendar_meeting function. """
@@ -427,11 +454,22 @@ class Flasktests(Modeltests):
 
         output = self.app.get('/ical/calendar/meeting/2/')
         self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
         data = self.wrap_content(
-            output.data, replacements=[
-                (r'UID:.*\n', 'UID:DUMMY_UID\r\n')
+            output_text, replacements=[
+                (r'UID:.*\n', 'UID:DUMMY_UID\r\n'),
+                (r'DTSTAMP:.*\n', 'DTSTAMP:20181221T120122Z\r\n'),
             ]
         )
+        # Newer python-vobject in the DTSTAMP field
+        if "DTSTAMP" in data:
+            string = "DTSTAMP:20181221T120122Z\r\nORGANIZER"
+            if six.PY3:
+                string = "DTSTAMP:20181221T120122Z\nORGANIZER"
+            expected_data = expected_data.replace("ORGANIZER", string)
+
+        if six.PY3:
+            data = data.replace("\r\n", "\n")
         self.assertEqual(data, expected_data)
 
         # Test meeting iCal with reminder
@@ -448,24 +486,37 @@ class Flasktests(Modeltests):
         )
         output = self.app.get('/ical/calendar/meeting/2/?reminder_delta=60')
         self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
         data = self.wrap_content(
-            output.data, replacements=[
-                (r'UID:.*\n', 'UID:DUMMY_UID\r\n')
+            output_text, replacements=[
+                (r'UID:.*\n', 'UID:DUMMY_UID\r\n'),
+                (r'DTSTAMP:.*\n', 'DTSTAMP:20181221T120122Z\r\n'),
             ]
         )
+        # Newer python-vobject in the DTSTAMP field
+        if "DTSTAMP" in data:
+            string = "DTSTAMP:20181221T120122Z\r\nORGANIZER"
+            if six.PY3:
+                string = "DTSTAMP:20181221T120122Z\nORGANIZER"
+            expected_data = expected_data.replace("ORGANIZER", string)
+
+        if six.PY3:
+            data = data.replace("\r\n", "\n")
         self.assertEqual(data, expected_data)
 
         # Test non numeric value for numeric data
         output = self.app.get('/ical/calendar/meeting/2/?reminder_delta=foo')
         self.assertEqual(output.status_code, 200)
-        self.assertFalse('VALARM' in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertNotIn('VALARM', output_text)
         self.assertEqual(data, expected_data)
 
         # Test with a reminder_delta value not in the default choice
         output = self.app.get('/ical/calendar/meeting/2/?reminder_delta=150')
         self.assertEqual(output.status_code, 200)
-        self.assertTrue('VALARM' in output.data)
-        self.assertTrue('TRIGGER:-PT2H30M' in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn('VALARM', output_text)
+        self.assertIn('TRIGGER:-PT2H30M', output_text)
 
     def test_view_meeting(self):
         """ Test the view_meeting function. """
@@ -473,19 +524,20 @@ class Flasktests(Modeltests):
 
         output = self.app.get('/meeting/5/')
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>Meeting "test-meeting-st-1" - Fedocal</title>'
-            in output.data)
-        self.assertTrue(
-            '<h2 class="orange">Meeting "test-meeting-st-1"</h2>'
-            in output.data)
-        self.assertTrue(
-            'This is a test meeting at the same time'
-            in output.data)
-        self.assertTrue('iCal export' in output.data)
-        self.assertTrue(
-            '<select id="ical-meeting-export-reminder-at"'
-            in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>Meeting "test-meeting-st-1" - Fedocal</title>',
+            output_text)
+        self.assertIn(
+            '<h2 class="orange">Meeting "test-meeting-st-1"</h2>',
+            output_text)
+        self.assertIn(
+            'This is a test meeting at the same time',
+            output_text)
+        self.assertIn('iCal export', output_text)
+        self.assertIn(
+            '<select id="ical-meeting-export-reminder-at"',
+            output_text)
 
     def test_view_meeting_page(self):
         """ Test the view_meeting_page function. """
@@ -493,72 +545,77 @@ class Flasktests(Modeltests):
 
         output = self.app.get('/meeting/5/1/')
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>Meeting "test-meeting-st-1" - Fedocal</title>'
-            in output.data)
-        self.assertTrue(
-            '<h2 class="orange">Meeting "test-meeting-st-1"</h2>'
-            in output.data)
-        self.assertTrue(
-            'This is a test meeting at the same time'
-            in output.data)
-        self.assertTrue(
-            '<a href="/ical/calendar/meeting/5/"'
-            in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>Meeting "test-meeting-st-1" - Fedocal</title>',
+            output_text)
+        self.assertIn(
+            '<h2 class="orange">Meeting "test-meeting-st-1"</h2>',
+            output_text)
+        self.assertIn(
+            'This is a test meeting at the same time',
+            output_text)
+        self.assertIn(
+            '<a href="/ical/calendar/meeting/5/"',
+            output_text)
 
         output = self.app.get('/meeting/5/0/')
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>Meeting "test-meeting-st-1" - Fedocal</title>'
-            not in output.data)
-        self.assertTrue(
-            '<h2 class="orange">Meeting "test-meeting-st-1"</h2>'
-            in output.data)
-        self.assertTrue(
-            'This is a test meeting at the same time'
-            in output.data)
-        self.assertTrue(
-            '<a href="/ical/calendar/meeting/5/"'
-            in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertNotIn(
+            '<title>Meeting "test-meeting-st-1" - Fedocal</title>',
+            output_text)
+        self.assertIn(
+            '<h2 class="orange">Meeting "test-meeting-st-1"</h2>',
+            output_text)
+        self.assertIn(
+            'This is a test meeting at the same time',
+            output_text)
+        self.assertIn(
+            '<a href="/ical/calendar/meeting/5/"',
+            output_text)
 
         # Invalid from_date
         output = self.app.get('/meeting/5/0/?from_date=foobar')
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>Meeting "test-meeting-st-1" - Fedocal</title>'
-            not in output.data)
-        self.assertTrue(
-            '<h2 class="orange">Meeting "test-meeting-st-1"</h2>'
-            in output.data)
-        self.assertTrue(
-            'This is a test meeting at the same time'
-            in output.data)
-        self.assertTrue(
-            '<a href="/ical/calendar/meeting/5/"'
-            in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertNotIn(
+            '<title>Meeting "test-meeting-st-1" - Fedocal</title>',
+            output_text)
+        self.assertIn(
+            '<h2 class="orange">Meeting "test-meeting-st-1"</h2>',
+            output_text)
+        self.assertIn(
+            'This is a test meeting at the same time',
+            output_text)
+        self.assertIn(
+            '<a href="/ical/calendar/meeting/5/"',
+            output_text)
 
         # Valid from_date
         output = self.app.get(
             '/meeting/5/0/?from_date=%s' % TODAY.strftime('%Y-%m-%d'))
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>Meeting "test-meeting-st-1" - Fedocal</title>'
-            not in output.data)
-        self.assertTrue(
-            '<h2 class="orange">Meeting "test-meeting-st-1"</h2>'
-            in output.data)
-        self.assertTrue(
-            'This is a test meeting at the same time'
-            in output.data)
-        self.assertTrue(
-            '<a href="/ical/calendar/meeting/5/"'
-            in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertNotIn(
+            '<title>Meeting "test-meeting-st-1" - Fedocal</title>',
+            output_text)
+        self.assertIn(
+            '<h2 class="orange">Meeting "test-meeting-st-1"</h2>',
+            output_text)
+        self.assertIn(
+            'This is a test meeting at the same time',
+            output_text)
+        self.assertIn(
+            '<a href="/ical/calendar/meeting/5/"',
+            output_text)
 
         output = self.app.get('/meeting/50/0/', follow_redirects=True)
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            'class="errors">No meeting could be found for this identifier</'
-            in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            'class="errors">No meeting could be found for this identifier</',
+            output_text)
 
     def test_is_admin(self):
         """ Test the is_admin function. """
@@ -634,81 +691,84 @@ class Flasktests(Modeltests):
         # Winter time
         output = self.app.get('/meeting/1/?from_date=2017-02-27')
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>Meeting "Fedora-fr-test-meeting" - Fedocal</title>'
-            in output.data)
-        self.assertTrue(
-            'Mon, February 27, 2017 - 14:00 UTC'
-            in output.data)
-        self.assertTrue(
-            'Mon, February 27, 2017 - 15:00:00 UTC'
-            in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>Meeting "Fedora-fr-test-meeting" - Fedocal</title>',
+            output_text)
+        self.assertIn(
+            'Mon, February 27, 2017 - 14:00 UTC',
+            output_text)
+        self.assertIn(
+            'Mon, February 27, 2017 - 15:00:00 UTC',
+            output_text)
 
         # Summer time
         output = self.app.get('/meeting/1/?from_date=2017-03-13')
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>Meeting "Fedora-fr-test-meeting" - Fedocal</title>'
-            in output.data)
-        self.assertTrue(
-            'Mon, March 13, 2017 - 13:00 UTC'
-            in output.data)
-        self.assertTrue(
-            'Mon, March 13, 2017 - 14:00 UTC'
-            in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>Meeting "Fedora-fr-test-meeting" - Fedocal</title>',
+            output_text)
+        self.assertIn(
+            'Mon, March 13, 2017 - 13:00 UTC', output_text)
+        self.assertIn(
+            'Mon, March 13, 2017 - 14:00 UTC', output_text)
 
         # Summer time in the US
         output = self.app.get(
             '/meeting/1/?from_date=2017-03-13&tzone=America/New_York')
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>Meeting "Fedora-fr-test-meeting" - Fedocal</title>'
-            in output.data)
-        self.assertTrue(
-            'Mon, March 13, 2017 - 13:00:00 UTC'
-            in output.data)
-        self.assertTrue(
-            'Mon, March 13, 2017 - 14:00:00 UTC'
-            in output.data)
-        self.assertTrue(
-            'Mon, March 13, 2017 - 09:00 America/New_York'
-            in output.data)
-        self.assertTrue(
-            'Mon, March 13, 2017 - 10:00 America/New_York'
-            in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>Meeting "Fedora-fr-test-meeting" - Fedocal</title>',
+            output_text)
+        self.assertIn(
+            'Mon, March 13, 2017 - 13:00:00 UTC',
+            output_text)
+        self.assertIn(
+            'Mon, March 13, 2017 - 14:00:00 UTC',
+            output_text)
+        self.assertIn(
+            'Mon, March 13, 2017 - 09:00 America/New_York',
+            output_text)
+        self.assertIn(
+            'Mon, March 13, 2017 - 10:00 America/New_York',
+            output_text)
 
         # Summer time in the US but not in Europe
         output = self.app.get(
             '/meeting/1/?from_date=2017-03-13&tzone=Europe/Paris')
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>Meeting "Fedora-fr-test-meeting" - Fedocal</title>'
-            in output.data)
-        self.assertTrue(
-            'Mon, March 13, 2017 - 13:00:00 UTC'
-            in output.data)
-        self.assertTrue(
-            'Mon, March 13, 2017 - 14:00:00 UTC'
-            in output.data)
-        self.assertTrue(
-            'Mon, March 13, 2017 - 14:00 Europe/Paris'
-            in output.data)
-        self.assertTrue(
-            'Mon, March 13, 2017 - 15:00 Europe/Paris'
-            in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>Meeting "Fedora-fr-test-meeting" - Fedocal</title>',
+            output_text)
+        self.assertIn(
+            'Mon, March 13, 2017 - 13:00:00 UTC',
+            output_text)
+        self.assertIn(
+            'Mon, March 13, 2017 - 14:00:00 UTC',
+            output_text)
+        self.assertIn(
+            'Mon, March 13, 2017 - 14:00 Europe/Paris',
+            output_text)
+        self.assertIn(
+            'Mon, March 13, 2017 - 15:00 Europe/Paris',
+            output_text)
 
         # Winter time again
         output = self.app.get('/meeting/1/?from_date=2017-11-20')
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>Meeting "Fedora-fr-test-meeting" - Fedocal</title>'
-            in output.data)
-        self.assertTrue(
-            'Mon, November 20, 2017 - 14:00 UTC'
-            in output.data)
-        self.assertTrue(
-            'Mon, November 20, 2017 - 15:00 UTC'
-            in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>Meeting "Fedora-fr-test-meeting" - Fedocal</title>',
+            output_text)
+        self.assertIn(
+            'Mon, November 20, 2017 - 14:00 UTC',
+            output_text)
+        self.assertIn(
+            'Mon, November 20, 2017 - 15:00 UTC',
+            output_text)
 
     def test_is_calendar_manager(self):
         """ Test the is_calendar_manager function. """
@@ -804,7 +864,8 @@ class Flasktests(Modeltests):
         with user_set(fedocal.APP, user):
             output = self.app.get('/login/', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue('<title>Home - Fedocal</title>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn('<title>Home - Fedocal</title>', output_text)
 
     def test_locations(self):
         """ Test the locations function. """
@@ -812,15 +873,14 @@ class Flasktests(Modeltests):
 
         output = self.app.get('/locations/')
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<h2>Locations</h2>'
-            in output.data)
-        self.assertTrue('href="/location/EMEA/">' in output.data)
-        self.assertTrue(
-            '<span class="calendar_name">EMEA</span>' in output.data)
-        self.assertTrue('href="/location/NA/">' in output.data)
-        self.assertTrue(
-            '<span class="calendar_name">NA</span>' in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn('<h2>Locations</h2>', output_text)
+        self.assertIn('href="/location/EMEA/">', output_text)
+        self.assertIn(
+            '<span class="calendar_name">EMEA</span>', output_text)
+        self.assertIn('href="/location/NA/">', output_text)
+        self.assertIn(
+            '<span class="calendar_name">NA</span>', output_text)
 
     def test_location(self):
         """ Test the location function. """
@@ -831,31 +891,34 @@ class Flasktests(Modeltests):
 
         output = self.app.get('/location/EMEA', follow_redirects=True)
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>EMEA - Fedocal</title>' in output.data)
-        self.assertTrue('<a href="/location/EMEA/">' in output.data)
-        self.assertTrue('title="Previous week">' in output.data)
-        self.assertTrue('title="Next week">' in output.data)
-        self.assertTrue(
-            '<input type="hidden" name="location" value="EMEA"/>'
-            in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>EMEA - Fedocal</title>', output_text)
+        self.assertIn('<a href="/location/EMEA/">', output_text)
+        self.assertIn('title="Previous week">', output_text)
+        self.assertIn('title="Next week">', output_text)
+        self.assertIn(
+            '<input type="hidden" name="location" value="EMEA"/>',
+            output_text)
 
         output = self.app.get('/location/NA/')
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>NA - Fedocal</title>' in output.data)
-        self.assertTrue('<a href="/location/NA/">' in output.data)
-        self.assertTrue('title="Previous week">' in output.data)
-        self.assertTrue('title="Next week">' in output.data)
-        self.assertTrue(
-            '<input type="hidden" name="location" value="NA"/>'
-            in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>NA - Fedocal</title>', output_text)
+        self.assertIn('<a href="/location/NA/">', output_text)
+        self.assertIn('title="Previous week">', output_text)
+        self.assertIn('title="Next week">', output_text)
+        self.assertIn(
+            '<input type="hidden" name="location" value="NA"/>',
+            output_text)
 
         output = self.app.get('/location/foobar/', follow_redirects=True)
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            'class="errors">No location named foobar could be found</'
-            in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            'class="errors">No location named foobar could be found</',
+            output_text)
 
     @flask10_only
     def test_admin(self):
@@ -864,36 +927,40 @@ class Flasktests(Modeltests):
         with user_set(fedocal.APP, user):
             output = self.app.get('/admin/', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue('<title>Home - Fedocal</title>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn('<title>Home - Fedocal</title>', output_text)
 
         user = FakeUser(['test'])
         with user_set(fedocal.APP, user):
             output = self.app.get('/admin/', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
                 '"errors">You are not a fedocal admin, you are not allowed '
-                'to access the admin part.</' in output.data)
+                'to access the admin part.</', output_text)
 
         user = FakeUser(fedocal.APP.config['ADMIN_GROUP'])
         with user_set(fedocal.APP, user):
             output = self.app.get('/admin/', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>Admin - Fedocal</title>' in output.data)
-            self.assertTrue(
-                '<h2>Admin interface</h2>' in output.data)
-            self.assertTrue(
-                '<option value="delete">Delete</option>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>Admin - Fedocal</title>', output_text)
+            self.assertIn(
+                '<h2>Admin interface</h2>', output_text)
+            self.assertIn(
+                '<option value="delete">Delete</option>', output_text)
 
             output = self.app.get(
                 '/admin/?calendar=test_calendar&action=edit',
                 follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>Home - Fedocal</title>' in output.data)
-            self.assertTrue(
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>Home - Fedocal</title>', output_text)
+            self.assertIn(
                 '<li class="errors">No calendar named test_calendar could '
-                'be found</li>' in output.data)
+                'be found</li>', output_text)
 
             self.__setup_db()
 
@@ -901,23 +968,25 @@ class Flasktests(Modeltests):
                 '/admin/?calendar=test_calendar&action=edit',
                 follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>Edit calendar - Fedocal</title>' in output.data)
-            self.assertTrue(
-                '<h2>Edit calendar "test_calendar"</h2>' in output.data)
-            self.assertTrue(
-                'type="text" value="test_calendar"></td>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>Edit calendar - Fedocal</title>', output_text)
+            self.assertIn(
+                '<h2>Edit calendar "test_calendar"</h2>', output_text)
+            self.assertIn(
+                'type="text" value="test_calendar"></td>', output_text)
 
             output = self.app.get(
                 '/admin/?calendar=test_calendar&action=delete',
                 follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>Delete calendar - Fedocal</title>' in output.data)
-            self.assertTrue(
-                '<h4>Calendar: test_calendar</h4>' in output.data)
-            self.assertTrue(
-                'value="Delete">' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>Delete calendar - Fedocal</title>', output_text)
+            self.assertIn(
+                '<h4>Calendar: test_calendar</h4>', output_text)
+            self.assertIn(
+                'value="Delete">', output_text)
 
     @flask10_only
     def test_add_calendar(self):
@@ -926,33 +995,36 @@ class Flasktests(Modeltests):
         with user_set(fedocal.APP, user):
             output = self.app.get('/calendar/add/', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
+            output_text = output.get_data(as_text=True)
             # discoveryfailure happens if there is no network
             self.assertTrue(
                 '<title>OpenID transaction in progress</title>'
-                in output.data or 'discoveryfailure' in output.data)
+                in output_text or 'discoveryfailure', output_text)
 
         user = FakeUser(['test'])
         with user_set(fedocal.APP, user):
             output = self.app.get('/calendar/add/', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
                 '"errors">You are not a fedocal admin, you are not allowed '
-                'to add calendars.</' in output.data)
+                'to add calendars.</', output_text)
 
         user = FakeUser(fedocal.APP.config['ADMIN_GROUP'])
         with user_set(fedocal.APP, user):
             output = self.app.get('/calendar/add/', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>Add calendar - Fedocal</title>' in output.data)
-            self.assertTrue(
-                'for="calendar_name">Calendar</label>' in output.data)
-            self.assertTrue(
-                'contact">Contact email' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>Add calendar - Fedocal</title>', output_text)
+            self.assertIn(
+                'for="calendar_name">Calendar</label>', output_text)
+            self.assertIn(
+                'contact">Contact email', output_text)
             self.assertEqual(
-                output.data.count('<span class="required">*</span>'), 3)
+                output_text.count('<span class="required">*</span>'), 3)
 
-            csrf_token = output.data.split(
+            csrf_token = output_text.split(
                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
 
             # calendar should have a name
@@ -965,8 +1037,9 @@ class Flasktests(Modeltests):
             output = self.app.post('/calendar/add/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<td>This field is required.</td>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<td>This field is required.</td>', output_text)
 
             # Works
             data = {
@@ -979,8 +1052,9 @@ class Flasktests(Modeltests):
             output = self.app.post('/calendar/add/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<li class="message">Calendar added</li>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<li class="message">Calendar added</li>', output_text)
 
             # This calendar already exists
             data = {
@@ -993,9 +1067,10 @@ class Flasktests(Modeltests):
             output = self.app.post('/calendar/add/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '="errors">Could not add this calendar to the database</'
-                in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '="errors">Could not add this calendar to the database</',
+                output_text)
 
     @flask10_only
     def test_delete_calendar(self):
@@ -1006,34 +1081,35 @@ class Flasktests(Modeltests):
         with user_set(fedocal.APP, user):
             output = self.app.get('/calendar/delete/1/', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
+            output_text = output.get_data(as_text=True)
             self.assertTrue(
                 '<li class="errors">You are not a fedocal admin, you are not'
-                ' allowed to delete the calendar.</l'
-                in output.data)
-            self.assertTrue(
-                '<title>Home - Fedocal</title>'
-                in output.data)
+                ' allowed to delete the calendar.</l',
+                output_text)
+            self.assertIn('<title>Home - Fedocal</title>', output_text)
 
         user = FakeUser(['packager'], username='kevin')
         with user_set(fedocal.APP, user):
             output = self.app.get('/calendar/delete/50/',
                                   follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '"errors">No calendar named 50 could be found</'
-                in output.data)
-            self.assertTrue('<title>Home - Fedocal</title>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '"errors">No calendar named 50 could be found</',
+                output_text)
+            self.assertIn('<title>Home - Fedocal</title>', output_text)
 
             output = self.app.get('/calendar/delete/test_calendar/')
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>Delete calendar - Fedocal</title>' in output.data)
-            self.assertTrue(
-                "Are you positively sure that's what you want to do?"
-                in output.data)
-            self.assertTrue(
-                'name="confirm_delete" type="checkbox" value="y"><label'
-                in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>Delete calendar - Fedocal</title>', output_text)
+            self.assertIn(
+                "Are you positively sure that's what you want to do?",
+                output_text)
+            self.assertIn(
+                'name="confirm_delete" type="checkbox" value="y"><label',
+                output_text)
 
             # No data
             data = {}
@@ -1041,16 +1117,17 @@ class Flasktests(Modeltests):
             output = self.app.post('/calendar/delete/test_calendar/',
                                    data=data, follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>Delete calendar - Fedocal</title>' in output.data)
-            self.assertTrue(
-                "Are you positively sure that's what you want to do?"
-                in output.data)
-            self.assertTrue(
-                'name="confirm_delete" type="checkbox" value="y"><label'
-                in output.data)
-
-            csrf_token = output.data.split(
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>Delete calendar - Fedocal</title>', output_text)
+            self.assertIn(
+                "Are you positively sure that's what you want to do?",
+                output_text)
+            self.assertIn(
+                'name="confirm_delete" type="checkbox" value="y"><label',
+                output_text)
+
+            csrf_token = output_text.split(
                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
 
             # No delete
@@ -1061,11 +1138,11 @@ class Flasktests(Modeltests):
             output = self.app.post('/calendar/delete/test_calendar/',
                                    data=data, follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>Home - Fedocal</title>' in output.data)
-            self.assertTrue(
-                '<span class="calendar_name">test_calendar</span>'
-                in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn('<title>Home - Fedocal</title>', output_text)
+            self.assertIn(
+                '<span class="calendar_name">test_calendar</span>',
+                output_text)
 
             # Delete
             data = {
@@ -1076,14 +1153,15 @@ class Flasktests(Modeltests):
             output = self.app.post('/calendar/delete/test_calendar/',
                                    data=data, follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>Home - Fedocal</title>' in output.data)
-            self.assertTrue(
-                '<li class="message">Calendar deleted</li>'
-                in output.data)
-            self.assertFalse(
-                '<span class="calendar_name">test_calendar</span>'
-                in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>Home - Fedocal</title>', output_text)
+            self.assertIn(
+                '<li class="message">Calendar deleted</li>',
+                output_text)
+            self.assertNotIn(
+                '<span class="calendar_name">test_calendar</span>',
+                output_text)
 
     @flask10_only
     def test_clear_calendar(self):
@@ -1095,35 +1173,37 @@ class Flasktests(Modeltests):
             output = self.app.get('/calendar/clear/1/',
                                   follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<li class="errors">No calendar named 1 could be found</li'
-                in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<li class="errors">No calendar named 1 could be found</li',
+                output_text)
 
             output = self.app.get('/calendar/clear/test_calendar/',
                                   follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
                 '<li class="errors">You are not an admin of this calendar, '
-                'you are not allowed to clear the calendar.</l'
-                in output.data)
-            self.assertTrue(
-                '<title>Home - Fedocal</title>'
-                in output.data)
+                'you are not allowed to clear the calendar.</l',
+                output_text)
+            self.assertIn(
+                '<title>Home - Fedocal</title>', output_text)
 
         user = FakeUser(['packager'], username='kevin')
         with user_set(fedocal.APP, user):
             output = self.app.get('/calendar/clear/test_calendar/')
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>Clear calendar - Fedocal</title>' in output.data)
-            self.assertTrue(
-                "Are you positively sure that's what you want to do?"
-                in output.data)
-            self.assertTrue(
-                'name="confirm_delete" type="checkbox" value="y"><label'
-                in output.data)
-            self.assertTrue(
-                '>Yes I want to clear this calendar</label>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>Clear calendar - Fedocal</title>', output_text)
+            self.assertIn(
+                "Are you positively sure that's what you want to do?",
+                output_text)
+            self.assertIn(
+                'name="confirm_delete" type="checkbox" value="y"><label',
+                output_text)
+            self.assertIn(
+                '>Yes I want to clear this calendar</label>', output_text)
 
             # No data
             data = {}
@@ -1131,16 +1211,17 @@ class Flasktests(Modeltests):
             output = self.app.post('/calendar/clear/test_calendar/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>Clear calendar - Fedocal</title>' in output.data)
-            self.assertTrue(
-                "Are you positively sure that's what you want to do?"
-                in output.data)
-            self.assertTrue(
-                'name="confirm_delete" type="checkbox" value="y"><label'
-                in output.data)
-
-            csrf_token = output.data.split(
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>Clear calendar - Fedocal</title>', output_text)
+            self.assertIn(
+                "Are you positively sure that's what you want to do?",
+                output_text)
+            self.assertIn(
+                'name="confirm_delete" type="checkbox" value="y"><label',
+                output_text)
+
+            csrf_token = output_text.split(
                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
 
             # No delete
@@ -1151,10 +1232,11 @@ class Flasktests(Modeltests):
             output = self.app.post('/calendar/clear/test_calendar/',
                                    data=data, follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>test_calendar - Fedocal</title>' in output.data)
-            self.assertTrue(
-                '<title>test_calendar - Fedocal</title>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>test_calendar - Fedocal</title>', output_text)
+            self.assertIn(
+                '<title>test_calendar - Fedocal</title>', output_text)
 
             # Delete
             data = {
@@ -1165,13 +1247,14 @@ class Flasktests(Modeltests):
             output = self.app.post('/calendar/clear/test_calendar/',
                                    data=data, follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>test_calendar - Fedocal</title>' in output.data)
-            self.assertTrue(
-                '<title>test_calendar - Fedocal</title>' in output.data)
-            self.assertTrue(
-                '<li class="message">Calendar cleared</li>'
-                in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>test_calendar - Fedocal</title>', output_text)
+            self.assertIn(
+                '<title>test_calendar - Fedocal</title>', output_text)
+            self.assertIn(
+                '<li class="message">Calendar cleared</li>',
+                output_text)
 
     @flask10_only
     def test_edit_calendar(self):
@@ -1183,32 +1266,33 @@ class Flasktests(Modeltests):
             output = self.app.get('/calendar/edit/test_calendar/',
                                   follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
                 '<li class="errors">You are not a fedocal admin, you are '
-                'not allowed to edit the calendar.</li>' in output.data)
-            self.assertTrue(
-                '<title>Home - Fedocal</title>'
-                in output.data)
+                'not allowed to edit the calendar.</li>', output_text)
+            self.assertIn(
+                '<title>Home - Fedocal</title>', output_text)
 
         user = FakeUser(['packager'], username='kevin')
         with user_set(fedocal.APP, user):
             output = self.app.get('/calendar/edit/1/',
                                   follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<li class="errors">No calendar named 1 could be found</li'
-                in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<li class="errors">No calendar named 1 could be found</li',
+                output_text)
 
             output = self.app.get('/calendar/edit/test_calendar/')
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>Edit calendar - Fedocal</title>' in output.data)
-            self.assertTrue(
-                '<h2>Edit calendar "test_calendar"</h2>'
-                in output.data)
-            self.assertTrue(
-                'class="submit positive button" value="Edit">'
-                in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>Edit calendar - Fedocal</title>', output_text)
+            self.assertIn(
+                '<h2>Edit calendar "test_calendar"</h2>', output_text)
+            self.assertIn(
+                'class="submit positive button" value="Edit">',
+                output_text)
 
             # No data
             data = {}
@@ -1216,16 +1300,16 @@ class Flasktests(Modeltests):
             output = self.app.post('/calendar/edit/test_calendar/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>Edit calendar - Fedocal</title>' in output.data)
-            self.assertTrue(
-                '<h2>Edit calendar "test_calendar"</h2>'
-                in output.data)
-            self.assertTrue(
-                'class="submit positive button" value="Edit">'
-                in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>Edit calendar - Fedocal</title>', output_text)
+            self.assertIn(
+                '<h2>Edit calendar "test_calendar"</h2>', output_text)
+            self.assertIn(
+                'class="submit positive button" value="Edit">',
+                output_text)
 
-            csrf_token = output.data.split(
+            csrf_token = output_text.split(
                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
 
             # No info except the csrf token
@@ -1236,14 +1320,15 @@ class Flasktests(Modeltests):
             output = self.app.post('/calendar/edit/test_calendar/',
                                    data=data, follow_redirects=True)
             self.assertEqual(output.status_code, 200)
+            output_text = output.get_data(as_text=True)
             self.assertEqual(
-                output.data.count('<td>This field is required.</td>'), 2)
-            self.assertTrue(
-                '<h2>Edit calendar "test_calendar"</h2>'
-                in output.data)
-            self.assertTrue(
-                'class="submit positive button" value="Edit">'
-                in output.data)
+                output_text.count('<td>This field is required.</td>'), 2)
+            self.assertIn(
+                '<h2>Edit calendar "test_calendar"</h2>',
+                output_text)
+            self.assertIn(
+                'class="submit positive button" value="Edit">',
+                output_text)
 
             # Edit
             data = {
@@ -1256,17 +1341,18 @@ class Flasktests(Modeltests):
             output = self.app.post('/calendar/edit/test_calendar/',
                                    data=data, follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>Election1 - Fedocal</title>' in output.data)
-            self.assertTrue(
-                '<li class="message">Calendar updated</li>'
-                in output.data)
-            self.assertFalse(
-                '<span class="calendar_name">test_calendar</span>'
-                in output.data)
-            self.assertFalse(
-                '<span class="calendar_name">election1</span>'
-                in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>Election1 - Fedocal</title>', output_text)
+            self.assertIn(
+                '<li class="message">Calendar updated</li>',
+                output_text)
+            self.assertNotIn(
+                '<span class="calendar_name">test_calendar</span>',
+                output_text)
+            self.assertNotIn(
+                '<span class="calendar_name">election1</span>',
+                output_text)
 
     @flask10_only
     def test_auth_logout(self):
@@ -1275,19 +1361,21 @@ class Flasktests(Modeltests):
         with user_set(fedocal.APP, user):
             output = self.app.get('/logout/', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue('<title>Home - Fedocal</title>' in output.data)
-            self.assertTrue(
-                '<li class="message">You have been logged out</li>'
-                in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn('<title>Home - Fedocal</title>', output_text)
+            self.assertIn(
+                '<li class="message">You have been logged out</li>',
+                output_text)
 
         user = None
         with user_set(fedocal.APP, user):
             output = self.app.get('/logout/', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue('<title>Home - Fedocal</title>' in output.data)
-            self.assertFalse(
-                '<li class="message">You have been logged out</li>'
-                in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn('<title>Home - Fedocal</title>', output_text)
+            self.assertNotIn(
+                '<li class="message">You have been logged out</li>',
+                output_text)
 
     @flask10_only
     def test_my_meetings(self):
@@ -1297,29 +1385,32 @@ class Flasktests(Modeltests):
         with user_set(fedocal.APP, user):
             output = self.app.get('/mine/', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '"errors">You must be in one more group than the CLA</li>'
-                in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '"errors">You must be in one more group than the CLA</li>',
+                output_text)
 
         user = FakeUser()
         user.cla_done=False
         with user_set(fedocal.APP, user):
             output = self.app.get('/mine/', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue('<title>Home - Fedocal</title>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn('<title>Home - Fedocal</title>', output_text)
 
         user = FakeUser(['packager'], username='pingou')
         with user_set(fedocal.APP, user):
             output = self.app.get('/mine/', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>My meetings - Fedocal</title>' in output.data)
-            self.assertTrue(
-                '<td> Full-day meeting </td>' in output.data)
-            self.assertTrue(
-                '<td> test-meeting2 </td>' in output.data)
-            self.assertTrue(
-                '<td> Test meeting with reminder </td>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>My meetings - Fedocal</title>', output_text)
+            self.assertIn(
+                '<td> Full-day meeting </td>', output_text)
+            self.assertIn(
+                '<td> test-meeting2 </td>', output_text)
+            self.assertIn(
+                '<td> Test meeting with reminder </td>', output_text)
 
     @flask10_only
     def test_add_meeting(self):
@@ -1329,34 +1420,36 @@ class Flasktests(Modeltests):
         with user_set(fedocal.APP, user):
             output = self.app.get('/calendar_test/add/', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            print(output.data)
-            self.assertTrue(
-                '"errors">No calendar named calendar_test could be found</'
-                in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '"errors">No calendar named calendar_test could be found</',
+                output_text)
 
             output = self.app.get('/test_calendar/add/', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
                 '<li class="errors">You are not one of the editors of this '
                 'calendar, or one of its admins, you are not allowed to add'
-                ' new meetings.</li>' in output.data)
-            self.assertTrue(
-                '<title>test_calendar - Fedocal</title>' in output.data)
+                ' new meetings.</li>', output_text)
+            self.assertIn(
+                '<title>test_calendar - Fedocal</title>', output_text)
 
         user = FakeUser(['fi-apprentice'], username='pingou')
         with user_set(fedocal.APP, user):
             output = self.app.get('/test_calendar/add/')
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>Add meeting - Fedocal</title>' in output.data)
-            self.assertTrue(
-                'meeting_name">Meeting name</label>' in output.data)
-            self.assertTrue(
-                'for="meeting_date">Date</label>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>Add meeting - Fedocal</title>', output_text)
+            self.assertIn(
+                'meeting_name">Meeting name</label>', output_text)
+            self.assertIn(
+                'for="meeting_date">Date</label>', output_text)
             self.assertEqual(
-                output.data.count('<span class="required">*</span>'), 5)
+                output_text.count('<span class="required">*</span>'), 5)
 
-            csrf_token = output.data.split(
+            csrf_token = output_text.split(
                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
 
             # Meeting should have a name
@@ -1372,8 +1465,9 @@ class Flasktests(Modeltests):
             output = self.app.post('/test_calendar/add/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<td>This field is required.</td>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<td>This field is required.</td>', output_text)
 
             # Format of the start time wrong
             data = {
@@ -1389,9 +1483,10 @@ class Flasktests(Modeltests):
             output = self.app.post('/test_calendar/add/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<td>Time must be of type &#34;HH:MM&#34;</td>'
-                in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<td>Time must be of type &#34;HH:MM&#34;</td>',
+                output_text)
 
             # Start time should have integer
             data = {
@@ -1407,9 +1502,10 @@ class Flasktests(Modeltests):
             output = self.app.post('/test_calendar/add/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<td>Time must be of type &#34;HH:MM&#34;</td>'
-                in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<td>Time must be of type &#34;HH:MM&#34;</td>',
+                output_text)
 
             # End date earlier than the start date
             data = {
@@ -1426,11 +1522,12 @@ class Flasktests(Modeltests):
             output = self.app.post('/test_calendar/add/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
                 '<li class="warnings">The start date of your meeting is '
-                'later than the stop date.</li>' in output.data)
-            self.assertTrue(
-                '<title>Add meeting - Fedocal</title>' in output.data)
+                'later than the stop date.</li>', output_text)
+            self.assertIn(
+                '<title>Add meeting - Fedocal</title>', output_text)
 
             # Invalid location
             data = {
@@ -1447,10 +1544,11 @@ class Flasktests(Modeltests):
             output = self.app.post('/test_calendar/add/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<td>Please use channel@server format!</td>' in output.data)
-            self.assertTrue(
-                '<title>Add meeting - Fedocal</title>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<td>Please use channel@server format!</td>', output_text)
+            self.assertIn(
+                '<title>Add meeting - Fedocal</title>', output_text)
 
             # Works
             data = {
@@ -1466,12 +1564,13 @@ class Flasktests(Modeltests):
             output = self.app.post('/test_calendar/add/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<li class="message">Meeting added</li>' in output.data)
-            self.assertTrue(
-                'href="/meeting/16/?from_date=' in output.data)
-            self.assertFalse(
-                'href="/meeting/17/?from_date=' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<li class="message">Meeting added</li>', output_text)
+            self.assertIn(
+                'href="/meeting/16/?from_date=', output_text)
+            self.assertNotIn(
+                'href="/meeting/17/?from_date=', output_text)
 
             # Works - with a wiki_link
             data = {
@@ -1488,12 +1587,13 @@ class Flasktests(Modeltests):
             output = self.app.post('/test_calendar/add/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<li class="message">Meeting added</li>' in output.data)
-            self.assertTrue(
-                'href="/meeting/17/?from_date=' in output.data)
-            self.assertFalse(
-                'href="/meeting/18/?from_date=' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<li class="message">Meeting added</li>', output_text)
+            self.assertIn(
+                'href="/meeting/17/?from_date=', output_text)
+            self.assertNotIn(
+                'href="/meeting/18/?from_date=', output_text)
 
             # Calendar disabled
             data = {
@@ -1509,13 +1609,14 @@ class Flasktests(Modeltests):
             output = self.app.post('/test_calendar_disabled/add/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
                 '<title>test_calendar_disabled - Fedocal</title>'
-                in output.data)
-            self.assertTrue(
+               , output_text)
+            self.assertIn(
                 '<li class="errors">This calendar is &#34;Disabled&#34;, '
                 'you are not allowed to add meetings anymore.</li>'
-                in output.data)
+               , output_text)
 
             # Fails - with an invalid email as recipient of the reminder
             data = {
@@ -1534,10 +1635,11 @@ class Flasktests(Modeltests):
             output = self.app.post('/test_calendar/add/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<h2>New meeting</h2>' in output.data)
-            self.assertTrue(
-                '<td>Invalid email address.</td>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<h2>New meeting</h2>', output_text)
+            self.assertIn(
+                '<td>Invalid email address.</td>', output_text)
 
             # Fails - one of the two email specified as recipient of the
             # reminder is invalid
@@ -1557,10 +1659,11 @@ class Flasktests(Modeltests):
             output = self.app.post('/test_calendar/add/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<h2>New meeting</h2>' in output.data)
-            self.assertTrue(
-                '<td>Invalid email address.</td>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<h2>New meeting</h2>', output_text)
+            self.assertIn(
+                '<td>Invalid email address.</td>', output_text)
 
             # Works - with one email as recipient of the reminder
             data = {
@@ -1579,16 +1682,17 @@ class Flasktests(Modeltests):
             output = self.app.post('/test_calendar/add/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<li class="message">Meeting added</li>' in output.data)
-            self.assertTrue(
-                'href="/meeting/17/?from_date=' in output.data)
-            self.assertTrue(
-                'href="/meeting/18/?from_date=' in output.data)
-            self.assertTrue(
-                'Reminder' in output.data)
-            self.assertFalse(
-                'href="/meeting/19/?from_date=' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<li class="message">Meeting added</li>', output_text)
+            self.assertIn(
+                'href="/meeting/17/?from_date=', output_text)
+            self.assertIn(
+                'href="/meeting/18/?from_date=', output_text)
+            self.assertIn(
+                'Reminder', output_text)
+            self.assertNotIn(
+                'href="/meeting/19/?from_date=', output_text)
 
             # Works - with two emails as recipient of the reminder
             data = {
@@ -1607,16 +1711,17 @@ class Flasktests(Modeltests):
             output = self.app.post('/test_calendar/add/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<li class="message">Meeting added</li>' in output.data)
-            self.assertTrue(
-                'href="/meeting/18/?from_date=' in output.data)
-            self.assertTrue(
-                'href="/meeting/19/?from_date=' in output.data)
-            self.assertTrue(
-                'Reminder2' in output.data)
-            self.assertFalse(
-                'href="/meeting/20/?from_date=' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<li class="message">Meeting added</li>', output_text)
+            self.assertIn(
+                'href="/meeting/18/?from_date=', output_text)
+            self.assertIn(
+                'href="/meeting/19/?from_date=', output_text)
+            self.assertIn(
+                'Reminder2', output_text)
+            self.assertNotIn(
+                'href="/meeting/20/?from_date=', output_text)
 
     @flask10_only
     def test_edit_meeting(self):
@@ -1626,47 +1731,51 @@ class Flasktests(Modeltests):
         with user_set(fedocal.APP, user):
             output = self.app.get('/meeting/edit/50/', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                'class="errors">The meeting #50 could not be found</li>'
-                in output.data)
-            self.assertTrue('<title>Home - Fedocal</title>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                'class="errors">The meeting #50 could not be found</li>',
+                output_text)
+            self.assertIn('<title>Home - Fedocal</title>', output_text)
 
             output = self.app.get('/meeting/edit/3/', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
                 '<li class="errors">You are not one of the manager of this '
-                'meeting, or an admin, you are not allowed to edit it.</li>'
-                in output.data)
-            self.assertTrue(
-                '<title>Meeting "test-meeting23h59" - Fedocal</title>'
-                in output.data)
+                'meeting, or an admin, you are not allowed to edit it.</li>',
+                output_text)
+            self.assertIn(
+                '<title>Meeting "test-meeting23h59" - Fedocal</title>',
+                output_text)
 
         user = FakeUser(['fi-apprentice'], username='kevin')
         with user_set(fedocal.APP, user):
             output = self.app.get('/meeting/edit/1/', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
                 '<li class="errors">You are not one of the manager of this '
-                'meeting, or an admin, you are not allowed to edit it.</li>'
-                in output.data)
-            self.assertTrue(
-                '<title>Meeting "Fedora-fr-test-meeting" - Fedocal</title>'
-                in output.data)
+                'meeting, or an admin, you are not allowed to edit it.</li>',
+                output_text)
+            self.assertIn(
+                '<title>Meeting "Fedora-fr-test-meeting" - Fedocal</title>',
+                output_text)
 
         user = FakeUser(['fi-apprentice'], username='pingou')
         with user_set(fedocal.APP, user):
             output = self.app.get('/meeting/edit/1/')
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>Edit meeting - Fedocal</title>' in output.data)
-            self.assertTrue(
-                'meeting_name">Meeting name</label>' in output.data)
-            self.assertTrue(
-                'for="meeting_date">Date</label>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>Edit meeting - Fedocal</title>', output_text)
+            self.assertIn(
+                'meeting_name">Meeting name</label>', output_text)
+            self.assertIn(
+                'for="meeting_date">Date</label>', output_text)
             self.assertEqual(
-                output.data.count('<span class="required">*</span>'), 6)
+                output_text.count('<span class="required">*</span>'), 6)
 
-            csrf_token = output.data.split(
+            csrf_token = output_text.split(
                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
 
             # Meeting should have a name
@@ -1682,8 +1791,9 @@ class Flasktests(Modeltests):
             output = self.app.post('/meeting/edit/1/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<td>This field is required.</td>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<td>This field is required.</td>', output_text)
 
             # No calendar provided
             data = {
@@ -1700,10 +1810,11 @@ class Flasktests(Modeltests):
             output = self.app.post('/meeting/edit/1/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<td>Not a valid choice</td>' in output.data)
-            self.assertTrue(
-                '<title>Edit meeting - Fedocal</title>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<td>Not a valid choice</td>', output_text)
+            self.assertIn(
+                '<title>Edit meeting - Fedocal</title>', output_text)
 
             # End date earlier than the start date
             data = {
@@ -1721,11 +1832,12 @@ class Flasktests(Modeltests):
             output = self.app.post('/meeting/edit/1/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
                 '<li class="warnings">The start date of your meeting is '
-                'later than the stop date.</li>' in output.data)
-            self.assertTrue(
-                '<title>Edit meeting - Fedocal</title>' in output.data)
+                'later than the stop date.</li>', output_text)
+            self.assertIn(
+                '<title>Edit meeting - Fedocal</title>', output_text)
 
             # Works
             data = {
@@ -1742,10 +1854,11 @@ class Flasktests(Modeltests):
             output = self.app.post('/meeting/edit/1/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<li class="message">Meeting updated</li>' in output.data)
-            self.assertTrue(
-                '<title>Meeting "guess what?" - Fedocal</title>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<li class="message">Meeting updated</li>', output_text)
+            self.assertIn(
+                '<title>Meeting "guess what?" - Fedocal</title>', output_text)
 
             # Calendar disabled
             data = {
@@ -1762,13 +1875,14 @@ class Flasktests(Modeltests):
             output = self.app.post('/meeting/edit/1/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>test_calendar_disabled - Fedocal</title>'
-                in output.data)
-            self.assertTrue(
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>test_calendar_disabled - Fedocal</title>',
+                output_text)
+            self.assertIn(
                 '<li class="errors">This calendar is &#34;Disabled&#34;, '
-                'you are not allowed to add meetings to it anymore.</li>'
-                in output.data)
+                'you are not allowed to add meetings to it anymore.</li>',
+                output_text)
 
         # Add a meeting to the test_calendar_disabled calendar
         obj = model.Meeting(  # id:16
@@ -1802,13 +1916,14 @@ class Flasktests(Modeltests):
             output = self.app.post('/meeting/edit/16/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>test_calendar_disabled - Fedocal</title>'
-                in output.data)
-            self.assertTrue(
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>test_calendar_disabled - Fedocal</title>',
+                output_text)
+            self.assertIn(
                 '<li class="errors">This calendar is &#34;Disabled&#34;, '
-                'you are not allowed to edit its meetings anymore.</li>'
-                in output.data)
+                'you are not allowed to edit its meetings anymore.</li>',
+                output_text)
 
         user = FakeUser(['packager'], username='pingou')
         with user_set(fedocal.APP, user):
@@ -1816,35 +1931,35 @@ class Flasktests(Modeltests):
             output = self.app.get(
                 '/meeting/edit/12/?from_date=foor', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>Edit meeting - Fedocal</title>' in output.data)
-            self.assertTrue(
-                '<h2>Edit meeting "Another past test meeting"</h2>'
-                in output.data)
-            self.assertTrue(
-                'meeting_name">Meeting name</label>'
-                in output.data)
-            self.assertTrue(
-                'for="meeting_date">Date</label>'
-                in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>Edit meeting - Fedocal</title>', output_text)
+            self.assertIn(
+                '<h2>Edit meeting "Another past test meeting"</h2>',
+                output_text)
+            self.assertIn(
+                'meeting_name">Meeting name</label>', output_text)
+            self.assertIn(
+                'for="meeting_date">Date</label>', output_text)
             self.assertEqual(
-                output.data.count('<span class="required">*</span>'), 6)
+                output_text.count('<span class="required">*</span>'), 6)
 
             output = self.app.get(
                 '/meeting/edit/12/?from_date=%s' % TODAY.strftime('%Y-%m-%d'),
                 follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>Edit meeting - Fedocal</title>' in output.data)
-            self.assertTrue(
-                '<h2>Edit meeting "Another past test meeting"</h2>'
-                in output.data)
-            self.assertTrue(
-                'meeting_name">Meeting name</label' in output.data)
-            self.assertTrue(
-                'for="meeting_date">Date</label>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>Edit meeting - Fedocal</title>', output_text)
+            self.assertIn(
+                '<h2>Edit meeting "Another past test meeting"</h2>',
+                output_text)
+            self.assertIn(
+                'meeting_name">Meeting name</label', output_text)
+            self.assertIn(
+                'for="meeting_date">Date</label>', output_text)
             self.assertEqual(
-                output.data.count('<span class="required">*</span>'), 6)
+                output_text.count('<span class="required">*</span>'), 6)
 
     @flask10_only
     def test_delete_meeting(self):
@@ -1854,70 +1969,75 @@ class Flasktests(Modeltests):
         with user_set(fedocal.APP, user):
             output = self.app.get('/meeting/delete/50/', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '"errors">No meeting with this identifier could be found.</'
-                in output.data)
-            self.assertTrue('<title>Home - Fedocal</title>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '"errors">No meeting with this identifier could be found.</',
+                output_text)
+            self.assertIn('<title>Home - Fedocal</title>', output_text)
 
             output = self.app.get('/meeting/delete/1/', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
                 '<li class="errors">You are not one of the manager of this '
-                'meeting, or an admin, you are not allowed to delete it.</l'
-                in output.data)
-            self.assertTrue(
-                '<title>Meeting "Fedora-fr-test-meeting" - Fedocal</title>'
-                in output.data)
+                'meeting, or an admin, you are not allowed to delete it.</l',
+                output_text)
+            self.assertIn(
+                '<title>Meeting "Fedora-fr-test-meeting" - Fedocal</title>',
+                output_text)
 
         user = FakeUser(['fi-apprentice'], username='kevin')
         with user_set(fedocal.APP, user):
             output = self.app.get('/meeting/delete/1/', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
                 '<li class="errors">You are not one of the manager of this '
-                'meeting, or an admin, you are not allowed to delete it.</l'
-                in output.data)
-            self.assertTrue(
-                '<title>Meeting "Fedora-fr-test-meeting" - Fedocal</title>'
-                in output.data)
+                'meeting, or an admin, you are not allowed to delete it.</l',
+                output_text)
+            self.assertIn(
+                '<title>Meeting "Fedora-fr-test-meeting" - Fedocal</title>',
+                output_text)
 
         user = FakeUser(['fi-apprentice'], username='pingou')
         with user_set(fedocal.APP, user):
             output = self.app.get('/meeting/delete/1/')
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>Delete meeting - Fedocal</title>' in output.data)
-            self.assertTrue(
-                '<h4>Meeting: Fedora-fr-test-meeting</h4>'
-                in output.data)
-            self.assertTrue(
-                "positively sure that's what you want to do?"
-                in output.data)
-            self.assertTrue(
-                'name="confirm_delete" type="checkbox" value="y"><label'
-                in output.data)
-            self.assertTrue(
-                '<input id="confirm_button" type="submit" class="submit positi'
-                in output.data)
-
-            csrf_token = output.data.split(
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>Delete meeting - Fedocal</title>', output_text)
+            self.assertIn(
+                '<h4>Meeting: Fedora-fr-test-meeting</h4>',
+                output_text)
+            self.assertIn(
+                "positively sure that's what you want to do?",
+                output_text)
+            self.assertIn(
+                'name="confirm_delete" type="checkbox" value="y"><label',
+                output_text)
+            self.assertIn(
+                '<input id="confirm_button" type="submit" class="submit positi',
+                output_text)
+
+            csrf_token = output_text.split(
                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
 
             # Invalid from_date
             output = self.app.get(
                 '/meeting/delete/1/?from_date=foobar', follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>Delete meeting - Fedocal</title>' in output.data)
-            self.assertTrue(
-                '<h4>Meeting: Fedora-fr-test-meeting</h4>'
-                in output.data)
-            self.assertTrue(
-                "positively sure that's what you want to do?"
-                in output.data)
-            self.assertTrue(
-                'name="confirm_delete" type="checkbox" value="y"><label'
-                in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>Delete meeting - Fedocal</title>', output_text)
+            self.assertIn(
+                '<h4>Meeting: Fedora-fr-test-meeting</h4>',
+                output_text)
+            self.assertIn(
+                "positively sure that's what you want to do?",
+                output_text)
+            self.assertIn(
+                'name="confirm_delete" type="checkbox" value="y"><label',
+                output_text)
 
             # Do not delete
             data = {
@@ -1928,8 +2048,9 @@ class Flasktests(Modeltests):
             output = self.app.post('/meeting/delete/1/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>test_calendar - Fedocal</title>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>test_calendar - Fedocal</title>', output_text)
 
             # Delete
             data = {
@@ -1940,10 +2061,11 @@ class Flasktests(Modeltests):
             output = self.app.post('/meeting/delete/1/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>test_calendar - Fedocal</title>' in output.data)
-            self.assertTrue(
-                '<li class="message">Meeting deleted</li>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>test_calendar - Fedocal</title>', output_text)
+            self.assertIn(
+                '<li class="message">Meeting deleted</li>', output_text)
 
             # Delete all
             data = {
@@ -1955,10 +2077,11 @@ class Flasktests(Modeltests):
             output = self.app.post('/meeting/delete/8/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>test_calendar - Fedocal</title>' in output.data)
-            self.assertTrue(
-                '<li class="message">Meeting deleted</li>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>test_calendar - Fedocal</title>', output_text)
+            self.assertIn(
+                '<li class="message">Meeting deleted</li>', output_text)
 
         # Add a meeting to the test_calendar_disabled calendar
         obj = model.Meeting(  # id:16
@@ -1987,13 +2110,14 @@ class Flasktests(Modeltests):
             output = self.app.post('/meeting/delete/16/', data=data,
                                    follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<title>test_calendar_disabled - Fedocal</title>'
-                in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>test_calendar_disabled - Fedocal</title>',
+                output_text)
             self.assertTrue(
                 '<li class="errors">This calendar is &#34;Disabled&#34;, '
-                'you are not allowed to delete its meetings anymore.</li>'
-                in output.data)
+                'you are not allowed to delete its meetings anymore.</li>',
+                output_text)
 
     def test_update_tz(self):
         """ Test the update_tz function. """
@@ -2001,15 +2125,18 @@ class Flasktests(Modeltests):
 
         output = self.app.get('/updatetz/?tzone=Europe/Paris',
                               follow_redirects=True)
-        self.assertTrue('<title>Home - Fedocal</title>' in output.data)
-        self.assertTrue('<li class="warnings">Invalid referred url</li>'
-                        in output.data)
+        self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
+        self.assertIn('<title>Home - Fedocal</title>', output_text)
+        self.assertIn(
+            '<li class="warnings">Invalid referred url</li>', output_text)
 
         output = self.app.get('/updatetz/',
                               follow_redirects=True)
-        self.assertTrue('<title>Home - Fedocal</title>' in output.data)
-        self.assertTrue('<li class="warnings">Invalid referred url</li>'
-                        in output.data)
+        self.assertIn('<title>Home - Fedocal</title>', output_text)
+        self.assertIn(
+            '<li class="warnings">Invalid referred url</li>',
+            output_text)
 
     def test_search(self):
         """ Test the search function. """
@@ -2018,29 +2145,39 @@ class Flasktests(Modeltests):
         # With '*'
         output = self.app.get('/search/?keyword=*meeting3*',
                               follow_redirects=True)
-        self.assertTrue('<title>Search - Fedocal</title>' in output.data)
-        self.assertTrue('<p>Result of your search for "*meeting3*"</p>'
-                        in output.data)
-        self.assertTrue('href="/meeting/4/?from_date='in output.data)
-        self.assertTrue('<p>Test meeting with past end_recursion....</p>'
-                        in output.data)
+        self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
+        self.assertIn('<title>Search - Fedocal</title>', output_text)
+        self.assertIn(
+            '<p>Result of your search for "*meeting3*"</p>',
+            output_text)
+        self.assertIn('href="/meeting/4/?from_date=', output_text)
+        self.assertIn(
+            '<p>Test meeting with past end_recursion....</p>',
+            output_text)
 
         # Without any '*'
         output = self.app.get('/search/?keyword=meeting3',
                               follow_redirects=True)
-        self.assertTrue('<title>Search - Fedocal</title>' in output.data)
-        self.assertTrue('<p>Result of your search for "meeting3*"</p>'
-                        in output.data)
-        self.assertFalse('href="/meeting/4/?from_date='in output.data)
-        self.assertFalse('href="/meeting/4/'in output.data)
-        self.assertFalse('d> <p>Test meeting with past end_recursion.</p> </'
-                        in output.data)
+        self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
+        self.assertIn('<title>Search - Fedocal</title>', output_text)
+        self.assertIn(
+            '<p>Result of your search for "meeting3*"</p>', output_text)
+        self.assertNotIn('href="/meeting/4/?from_date=', output_text)
+        self.assertNotIn('href="/meeting/4/', output_text)
+        self.assertNotIn(
+            'd> <p>Test meeting with past end_recursion.</p> </',
+            output_text)
 
         output = self.app.get('/search/',
                               follow_redirects=True)
-        self.assertTrue('<title>Home - Fedocal</title>')
-        self.assertTrue('class="errors">No keyword provided for the search</'
-                        in output.data)
+        self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
+        self.assertIn('<title>Home - Fedocal</title>', output_text)
+        self.assertIn(
+            'class="errors">No keyword provided for the search</',
+            output_text)
 
     def test_goto(self):
         """ Test the goto function. """
@@ -2055,90 +2192,113 @@ class Flasktests(Modeltests):
         }
 
         output = self.app.get('/goto/', follow_redirects=True)
-        self.assertTrue('<title>Home - Fedocal</title>' in output.data)
-        self.assertTrue('<li class="errors">No calendar specified</li>'
-                        in output.data)
+        self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
+        self.assertIn('<title>Home - Fedocal</title>', output_text)
+        self.assertIn(
+            '<li class="errors">No calendar specified</li>', output_text)
 
         output = self.app.get('/goto/?calendar=test_calendar',
                               follow_redirects=True)
-        self.assertTrue('<title>test_calendar - Fedocal</title>'
-                        in output.data)
-        self.assertTrue('<p>This is a test calendar</p>'
-                        in output.data)
+        self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
+        self.assertIn(
+            '<p>This is a test calendar</p>', output_text)
 
         output = self.app.get('/goto/?calendar=test_calendar&month=3',
                               follow_redirects=True)
-        self.assertTrue('<title>test_calendar - Fedocal</title>'
-                        in output.data)
-        self.assertTrue('<p>This is a test calendar</p>'
-                        in output.data)
+        self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
+        self.assertIn(
+            '<p>This is a test calendar</p>', output_text)
 
         output = self.app.get('/goto/?calendar=test_calendar&month=3&day=1',
                               follow_redirects=True)
-        self.assertTrue('<title>test_calendar - Fedocal</title>'
-                        in output.data)
-        self.assertTrue('<p>This is a test calendar</p>'
-                        in output.data)
+        self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
+        self.assertIn(
+            '<p>This is a test calendar</p>', output_text)
 
         output = self.app.get(
             '/goto/?calendar=test_calendar&year=2010&month=3&day=1',
             follow_redirects=True)
-        self.assertTrue('<title>test_calendar - Fedocal</title>'
-                        in output.data)
-        self.assertTrue('<p>This is a test calendar</p>'
-                        in output.data)
+        self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
+        self.assertIn(
+            '<p>This is a test calendar</p>', output_text)
 
         output = self.app.get(
             '/goto/?calendar=test_calendar&year=2010&month=3&day=a',
             follow_redirects=True)
-        self.assertTrue('<title>test_calendar - Fedocal</title>'
-                        in output.data)
-        self.assertTrue('<li class="errors">Invalid date specified</li>'
-                        in output.data)
-        self.assertTrue('<p>This is a test calendar</p>'
-                        in output.data)
+        self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
+        self.assertIn(
+            '<li class="errors">Invalid date specified</li>', output_text)
+        self.assertIn(
+            '<p>This is a test calendar</p>', output_text)
 
         output = self.app.get(
             '/goto/?calendar=test_calendar&year=2010&month=a',
             follow_redirects=True)
-        self.assertTrue('<title>test_calendar - Fedocal</title>'
-                        in output.data)
-        self.assertTrue('<li class="errors">Invalid date specified</li>'
-                        in output.data)
-        self.assertTrue('<p>This is a test calendar</p>'
-                        in output.data)
+        self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
+        self.assertIn(
+            '<li class="errors">Invalid date specified</li>', output_text)
+        self.assertIn(
+            '<p>This is a test calendar</p>', output_text)
 
         output = self.app.get('/goto/?calendar=test_calendar&year=a',
                               follow_redirects=True)
-        self.assertTrue('<title>test_calendar - Fedocal</title>'
-                        in output.data)
-        self.assertTrue('<li class="errors">Invalid date specified</li>'
-                        in output.data)
-        self.assertTrue('<p>This is a test calendar</p>'
-                        in output.data)
+        self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
+        self.assertIn(
+            '<li class="errors">Invalid date specified</li>', output_text)
+        self.assertIn(
+            '<p>This is a test calendar</p>', output_text)
 
         output = self.app.get('/goto/?calendar=test_calendar&year=1870',
                               follow_redirects=True)
-        self.assertTrue('<title>test_calendar - Fedocal</title>'
-                        in output.data)
-        self.assertTrue('="warnings">Dates before 1900 are not allowed</li'
-                        in output.data)
-        self.assertTrue('<p>This is a test calendar</p>'
-                        in output.data)
+        self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
+        self.assertIn(
+            '="warnings">Dates before 1900 are not allowed</li',
+            output_text)
+        self.assertIn(
+            '<p>This is a test calendar</p>', output_text)
 
         output = self.app.get('/goto/?calendar=test_calendar&type=list',
                               follow_redirects=True)
-        self.assertTrue('<title>test_calendar - Fedocal</title>'
-                        in output.data)
-        self.assertTrue('<p>This is a test calendar</p>'
-                        in output.data)
+        self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
+        self.assertIn(
+            '<p>This is a test calendar</p>', output_text)
 
         output = self.app.get('/goto/?calendar=test_calendar&type=foobar',
                               follow_redirects=True)
-        self.assertTrue('<title>test_calendar - Fedocal</title>'
-                        in output.data)
-        self.assertTrue('<p>This is a test calendar</p>'
-                        in output.data)
+        self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>test_calendar - Fedocal</title>', output_text)
+        self.assertIn(
+            '<p>This is a test calendar</p>', output_text)
 
     @flask10_only
     def test_upload_calendar(self):
@@ -2150,69 +2310,77 @@ class Flasktests(Modeltests):
             output = self.app.get('/calendar/upload/1/',
                                   follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
-                '<li class="errors">No calendar named 1 could be found</li'
-                in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<li class="errors">No calendar named 1 could be found</li',
+                output_text)
 
             output = self.app.get('/calendar/upload/test_calendar/',
                                   follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue(
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
                 '<li class="errors">You are not an admin for this calendar, '
-                'you are not allowed to upload a iCalendar file to it.</l'
-                in output.data)
-            self.assertTrue(
-                '<title>Home - Fedocal</title>'
-                in output.data)
+                'you are not allowed to upload a iCalendar file to it.</l',
+                output_text)
+            self.assertIn(
+                '<title>Home - Fedocal</title>', output_text)
 
         user = FakeUser(['packager'], username='kevin')
         with user_set(fedocal.APP, user):
             output = self.app.get('/calendar/upload/test_calendar/',
                                   follow_redirects=True)
             self.assertEqual(output.status_code, 200)
-            self.assertTrue('<title>Upload calendar - Fedocal</title>'
-                            in output.data)
-            self.assertTrue('<h2>Upload calendar</h2>' in output.data)
+            output_text = output.get_data(as_text=True)
+            self.assertIn(
+                '<title>Upload calendar - Fedocal</title>', output_text)
+            self.assertIn('<h2>Upload calendar</h2>', output_text)
 
-            csrf_token = output.data.split(
+            csrf_token = output_text.split(
                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
 
-            with open(ICS_FILE) as stream:
+            with open(ICS_FILE, 'rb') as stream:
                 data = {
                     'ics_file': stream,
+                    'enctype': 'multipart/form-data',
                     'csrf_token': csrf_token,
                 }
                 output = self.app.post('/calendar/upload/test_calendar/',
                                        follow_redirects=True, data=data)
                 self.assertEqual(output.status_code, 200)
-                if '<li class="error">' not in output.data:
-                    self.assertTrue('<title>test_calendar - Fedocal</title>'
-                                    in output.data)
-                    self.assertTrue('<p>This is a test calendar</p>'
-                                    in output.data)
-                    self.assertTrue(
-                        'li class="message">Calendar uploaded</li>'
-                        in output.data)
+                output_text = output.get_data(as_text=True)
+                if '<li class="error">' not in output_text:
+                    self.assertIn(
+                        '<title>test_calendar - Fedocal</title>',
+                        output_text)
+                    self.assertIn(
+                        '<p>This is a test calendar</p>', output_text)
+                    self.assertIn(
+                        'li class="message">Calendar uploaded</li>',
+                        output_text)
                 else:
-                    self.assertTrue(
+                    self.assertIn(
                         '<li class="error">The submitted candidate has the '
                         'MIME type &#34;application/octet-stream&#34; which '
-                        'is not an allowed MIME type</li>' in output.data)
+                        'is not an allowed MIME type</li>', output_text)
 
-            with open(ICS_FILE_NOTOK) as stream:
+            with open(ICS_FILE_NOTOK, 'rb') as stream:
                 data = {
                     'ics_file': stream,
+                    'enctype': 'multipart/form-data',
                     'csrf_token': csrf_token,
                 }
                 output = self.app.post('/calendar/upload/test_calendar/',
                                        follow_redirects=True, data=data)
                 self.assertEqual(output.status_code, 200)
-                self.assertTrue('<title>Upload calendar - Fedocal</title>'
-                                in output.data)
-                self.assertTrue('<li class="error">The submitted candidate '
-                                'has the file extension &#34;txt&#34; which is'
-                                ' not an allowed format</li>'
-                                in output.data)
+                output_text = output.get_data(as_text=True)
+                self.assertIn(
+                    '<title>Upload calendar - Fedocal</title>',
+                    output_text)
+                self.assertIn(
+                    '<li class="error">The submitted candidate has the file '
+                    'extension &#34;txt&#34; which is not an allowed '
+                    'format</li>', output_text)
 
     @flask10_only
     def test_markdown_preview(self):
@@ -2227,7 +2395,8 @@ class Flasktests(Modeltests):
             }
             output = self.app.post('/markdown/', data=data)
             self.assertEqual(output.status_code, 200)
-            self.assertEqual(output.data, ' <p><code>test</code></p> ')
+            output_text = output.get_data(as_text=True)
+            self.assertEqual(output_text, ' <p><code>test</code></p> ')
 
 
 if __name__ == '__main__':
diff --git a/tests/test_flask_api.py b/tests/test_flask_api.py
index e870a7d..cb23b0a 100644
--- a/tests/test_flask_api.py
+++ b/tests/test_flask_api.py
@@ -26,9 +26,7 @@
 
  fedocal.model test script
 """
-
-__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4']
-import pkg_resources
+from __future__ import unicode_literals, absolute_import, print_function
 
 import json
 import unittest
@@ -38,6 +36,8 @@ import os
 from datetime import date
 from datetime import timedelta
 
+import six
+
 sys.path.insert(0, os.path.join(os.path.dirname(
     os.path.abspath(__file__)), '..'))
 
@@ -51,10 +51,12 @@ from tests import Modeltests, TODAY
 class FlaskApitests(Modeltests):
     """ Flask application API tests. """
 
+    maxDiff = None
+
     def __setup_db(self):
         """ Add a calendar and some meetings so that we can play with
         something. """
-        from test_meeting import Meetingtests
+        from .test_meeting import Meetingtests
         meeting = Meetingtests('test_init_meeting')
         meeting.session = self.session
         meeting.test_init_meeting()
@@ -75,19 +77,23 @@ class FlaskApitests(Modeltests):
 
         output = self.app.get('/api/')
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            '<title>API - Fedocal</title>' in output.data)
-        self.assertTrue(
-            '<h1 class="title">API documentation</h1>' in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '<title>API - Fedocal</title>', output_text)
+        self.assertIn(
+            '<h1 class="title">API documentation</h1>', output_text)
 
     def test_api_date_default(self):
         """ Test the api_date_default function. """
         output = self.app.get('/api/meetings/?calendar=test_calendar')
         self.assertEqual(output.status_code, 400)
+        data = json.loads(output.get_data(as_text=True))
         self.assertEqual(
-            output.data,
-            '{"meetings": [], '
-            '"error": "Invalid calendar provided: test_calendar"}')
+            data,
+            {
+                "meetings": [],
+                "error": "Invalid calendar provided: test_calendar"
+            })
 
         start_date = date.today() - timedelta(days=30)
         end_date = date.today() + timedelta(days=180)
@@ -96,26 +102,21 @@ class FlaskApitests(Modeltests):
 
         output = self.app.get('/api/meetings/?calendar=test_calendar')
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            ' "meeting_manager": ["pingou", "shaiton"],'
-            in output.data)
-        self.assertTrue(
-            '"meeting_name": "test-meeting2"' in output.data)
-        self.assertEqual(
-            output.data.count('meeting_name'),
-            49)
-        data = json.loads(output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            ' "meeting_manager": ["pingou", "shaiton"],', output_text)
+        self.assertIn('"meeting_name": "test-meeting2"', output_text)
+        self.assertEqual(output_text.count('meeting_name'), 49)
+        data = json.loads(output.get_data(as_text=True))
         self.assertEqual(
             data['arguments']['start'],
             start_date.strftime('%Y-%m-%d'))
 
         output = self.app.get('/api/meetings/?calendar=test_calendar4')
-        self.assertEqual(
-            output.status_code,
-            200)
-        self.assertEqual(
-            output.data.count('meeting_name'),
-            3)
+        self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
+        self.assertEqual(output.status_code, 200)
+        self.assertEqual(output_text.count('meeting_name'), 3)
 
     def test_api_date(self):
         """ Test the api_date function. """
@@ -126,10 +127,13 @@ class FlaskApitests(Modeltests):
             )
         )
         self.assertEqual(output.status_code, 400)
+        data = json.loads(output.get_data(as_text=True))
         self.assertEqual(
-            output.data,
-            '{"meetings": [], '
-            '"error": "Invalid calendar provided: foobar"}')
+            data,
+            {
+                "meetings": [],
+                "error": "Invalid calendar provided: foobar"
+            })
 
         self.__setup_db()
 
@@ -138,13 +142,19 @@ class FlaskApitests(Modeltests):
                 TODAY - timedelta(days=50), end_date - timedelta(days=45)
             )
         )
+        self.assertEqual(output.status_code, 200)
+        data = json.loads(output.get_data(as_text=True))
         self.assertEqual(
-            output.data,
-            '{"meetings": [], "arguments": {"start": "%s", '
-            '"calendar": "test_calendar", "end": "%s", "location": null}}' % (
-                (TODAY - timedelta(days=50)).strftime('%Y-%m-%d'),
-                (end_date - timedelta(days=45)).strftime('%Y-%m-%d')
-            )
+            data,
+            {
+                "meetings": [],
+                "arguments": {
+                    "start": "%s" % (TODAY - timedelta(days=50)).strftime('%Y-%m-%d'),
+                    "calendar": "test_calendar",
+                    "end": "%s" % (end_date - timedelta(days=45)).strftime('%Y-%m-%d'),
+                    "location": None
+                }
+            }
         )
 
         output = self.app.get(
@@ -153,15 +163,12 @@ class FlaskApitests(Modeltests):
             )
         )
         self.assertEqual(output.status_code, 200)
-        self.assertTrue(
-            ' "meeting_manager": ["pingou", "shaiton"],'
-            in output.data)
-        self.assertTrue(
-            '"meeting_name": "Another test meeting2",'
-            in output.data)
-        self.assertEqual(
-            output.data.count('meeting_name'),
-            8)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            ' "meeting_manager": ["pingou", "shaiton"],', output_text)
+        self.assertIn(
+            '"meeting_name": "Another test meeting2",', output_text)
+        self.assertEqual(output_text.count('meeting_name'), 8)
 
         end_date = TODAY + timedelta(days=2)
         output = self.app.get(
@@ -170,7 +177,8 @@ class FlaskApitests(Modeltests):
             )
         )
         self.assertEqual(output.status_code, 200)
-        self.assertEqual(output.data.count('meeting_name'), 2)
+        output_text = output.get_data(as_text=True)
+        self.assertEqual(output_text.count('meeting_name'), 2)
 
         end_date = TODAY + timedelta(days=2)
         output = self.app.get(
@@ -179,7 +187,8 @@ class FlaskApitests(Modeltests):
             )
         )
         self.assertEqual(output.status_code, 200)
-        self.assertEqual(output.data.count('meeting_name'), 6)
+        output_text = output.get_data(as_text=True)
+        self.assertEqual(output_text.count('meeting_name'), 6)
 
     def test_api_date_error(self):
         """ Test the api_date function with wrong input. """
@@ -189,53 +198,61 @@ class FlaskApitests(Modeltests):
             '/api/meetings/?calendar=test_calendar&start=%s&end=2012-09-aw'
             % (TODAY))
         self.assertEqual(output.status_code, 400)
-        self.assertTrue(
-            '"error": "Invalid end date format: '
-            in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn('"error": "Invalid end date format: ', output_text)
 
     def test_api_place_default(self):
         """ Test the api_place_default function. """
+        start_date = date.today() - timedelta(days=30)
+        end_date = date.today() + timedelta(days=180)
 
         output = self.app.get(
             '/api/meetings/?location=EMEA')
         self.assertEqual(output.status_code, 200)
-        start_date = date.today() - timedelta(days=30)
-        end_date = date.today() + timedelta(days=180)
+        data = json.loads(output.get_data(as_text=True))
         self.assertEqual(
-            output.data,
-            '{"meetings": [], '
-            '"arguments": {'
-            '"start": "%s", '
-            '"calendar": null, '
-            '"end": "%s", '
-            '"location": "EMEA"}'
-            '}' % (start_date.strftime('%Y-%m-%d'),
-                   end_date.strftime('%Y-%m-%d')))
+            data,
+            {
+                "meetings": [],
+                "arguments": {
+                    "start": start_date.strftime('%Y-%m-%d'),
+                    "calendar": None,
+                    "end": end_date.strftime('%Y-%m-%d'),
+                    "location": "EMEA"
+                }
+            }
+        )
 
         self.__setup_db()
 
         output = self.app.get(
             '/api/meetings/?calendar=test_calendar4&location=APAC')
         self.assertEqual(output.status_code, 200)
+        data = json.loads(output.get_data(as_text=True))
         self.assertEqual(
-            output.data,
-            '{"meetings": [], "arguments": {"start": "%s", '
-            '"calendar": "test_calendar4", "end": "%s", '
-            '"location": "APAC"}}' % (
-                start_date.strftime('%Y-%m-%d'),
-                end_date.strftime('%Y-%m-%d')
-            )
+            data,
+            {
+                "meetings": [],
+                "arguments": {
+                    "start": start_date.strftime('%Y-%m-%d'),
+                    "calendar": "test_calendar4",
+                    "end": end_date.strftime('%Y-%m-%d'),
+                    "location": "APAC"
+                }
+            }
         )
 
         output = self.app.get(
             '/api/meetings/?calendar=test_calendar4&location=NA')
         self.assertEqual(output.status_code, 200)
-        self.assertEqual(output.data.count('meeting_name'), 1)
+        output_text = output.get_data(as_text=True)
+        self.assertEqual(output_text.count('meeting_name'), 1)
 
         output = self.app.get(
             '/api/meetings/?calendar=test_calendar4&location=EMEA')
         self.assertEqual(output.status_code, 200)
-        self.assertEqual(output.data.count('meeting_name'), 2)
+        output_text = output.get_data(as_text=True)
+        self.assertEqual(output_text.count('meeting_name'), 2)
 
     def test_api_place(self):
         """ Test the api_place function. """
@@ -246,14 +263,18 @@ class FlaskApitests(Modeltests):
             )
         )
         self.assertEqual(output.status_code, 200)
+        data = json.loads(output.get_data(as_text=True))
         self.assertEqual(
-            output.data,
-            '{"meetings": [], "arguments": {"start": "%s", '
-            '"calendar": null, "end": "%s", '
-            '"location": "APAC"}}' % (
-                TODAY.strftime('%Y-%m-%d'),
-                end_date.strftime('%Y-%m-%d')
-            )
+            data,
+            {
+                "meetings": [],
+                "arguments": {
+                    "start": TODAY.strftime('%Y-%m-%d'),
+                    "calendar": None,
+                    "end": end_date.strftime('%Y-%m-%d'),
+                    "location": "APAC"
+                }
+            }
         )
 
         self.__setup_db()
@@ -265,14 +286,18 @@ class FlaskApitests(Modeltests):
             )
         )
         self.assertEqual(output.status_code, 200)
+        data = json.loads(output.get_data(as_text=True))
         self.assertEqual(
-            output.data,
-            '{"meetings": [], "arguments": {"start": "%s", '
-            '"calendar": "test_calendar4", "end": "%s", '
-            '"location": "APAC"}}' % (
-                TODAY.strftime('%Y-%m-%d'),
-                end_date.strftime('%Y-%m-%d')
-            )
+            data,
+            {
+                "meetings": [],
+                "arguments": {
+                    "start": TODAY.strftime('%Y-%m-%d'),
+                    "calendar": "test_calendar4",
+                    "end": end_date.strftime('%Y-%m-%d'),
+                    "location": "APAC"
+                }
+            }
         )
 
         output = self.app.get(
@@ -282,7 +307,8 @@ class FlaskApitests(Modeltests):
             )
         )
         self.assertEqual(output.status_code, 200)
-        self.assertEqual(output.data.count('meeting_name'), 1)
+        output_text = output.get_data(as_text=True)
+        self.assertEqual(output_text.count('meeting_name'), 1)
 
         output = self.app.get(
             '/api/meetings/?calendar=test_calendar4&location=EMEA'
@@ -291,7 +317,8 @@ class FlaskApitests(Modeltests):
             )
         )
         self.assertEqual(output.status_code, 200)
-        self.assertEqual(output.data.count('meeting_name'), 2)
+        output_text = output.get_data(as_text=True)
+        self.assertEqual(output_text.count('meeting_name'), 2)
 
         output = self.app.get(
             '/api/meetings/?location=EMEA&start=%s&end=%s' % (
@@ -299,7 +326,8 @@ class FlaskApitests(Modeltests):
             )
         )
         self.assertEqual(output.status_code, 200)
-        self.assertEqual(output.data.count('meeting_name'), 2)
+        output_text = output.get_data(as_text=True)
+        self.assertEqual(output_text.count('meeting_name'), 2)
 
         end_date = TODAY + timedelta(days=1)
 
@@ -310,14 +338,18 @@ class FlaskApitests(Modeltests):
             )
         )
         self.assertEqual(output.status_code, 200)
+        data = json.loads(output.get_data(as_text=True))
         self.assertEqual(
-            output.data,
-            '{"meetings": [], "arguments": {"start": "%s", '
-            '"calendar": "test_calendar4", "end": "%s", '
-            '"location": "NA"}}' % (
-                TODAY.strftime('%Y-%m-%d'),
-                end_date.strftime('%Y-%m-%d')
-            )
+            data,
+            {
+                "arguments": {
+                    "start": TODAY.strftime('%Y-%m-%d'),
+                    "calendar": "test_calendar4",
+                    "end": end_date.strftime('%Y-%m-%d'),
+                    "location": "NA"
+                },
+                "meetings": []
+            }
         )
 
         output = self.app.get(
@@ -327,14 +359,18 @@ class FlaskApitests(Modeltests):
             )
         )
         self.assertEqual(output.status_code, 200)
+        data = json.loads(output.get_data(as_text=True))
         self.assertEqual(
-            output.data,
-            '{"meetings": [], "arguments": {"start": "%s", '
-            '"calendar": "test_calendar4", "end": "%s", '
-            '"location": "EMEA"}}' % (
-                TODAY.strftime('%Y-%m-%d'),
-                end_date.strftime('%Y-%m-%d')
-            )
+            data,
+            {
+                "meetings": [],
+                "arguments": {
+                    "start": TODAY.strftime('%Y-%m-%d'),
+                    "calendar": "test_calendar4",
+                    "end": end_date.strftime('%Y-%m-%d'),
+                    "location": "EMEA"
+                }
+            }
         )
 
     def test_api_place_error(self):
@@ -347,69 +383,85 @@ class FlaskApitests(Modeltests):
             '&end=%s&start=2012-12-as' % (end_date)
         )
         self.assertEqual(output.status_code, 400)
-        self.assertTrue(
-            '"error": "Invalid start date format: '
-            in output.data)
+        output_text = output.get_data(as_text=True)
+        self.assertIn(
+            '"error": "Invalid start date format: ', output_text)
 
     def test_api_calendars(self):
         """ Test the api_calendars function. """
         output = self.app.get('/api/calendars/')
         self.assertEqual(output.status_code, 200)
+        output_text = output.get_data(as_text=True)
         self.assertEqual(
-            output.data,
+            output_text,
             '{"calendars": []}')
 
         self.__setup_db()
 
         output = self.app.get('/api/calendars/')
         self.assertEqual(output.status_code, 200)
-        self.assertEqual(output.data.count('calendar_name'), 5)
+        output_text = output.get_data(as_text=True)
+        self.assertEqual(output_text.count('calendar_name'), 5)
 
         output = self.app.get('/api/calendars/?callback="abcd"')
         self.assertEqual(output.status_code, 200)
-        self.assertEqual(output.data.count('calendar_name'), 5)
-        self.assertTrue(output.data.startswith('"abcd"([\'{"calendars":'))
+        output_text = output.get_data(as_text=True)
+        self.assertEqual(output_text.count('calendar_name'), 5)
+        if six.PY3:
+            self.assertTrue(output_text.startswith('"abcd"([b\'{"calendars":'))
+        else:
+            self.assertTrue(output_text.startswith('"abcd"([\'{"calendars":'))
 
     def test_api_locations(self):
         """ Test the api_locations function. """
         output = self.app.get('/api/locations/')
         self.assertEqual(output.status_code, 200)
-        self.assertEqual(
-            output.data,
-            '{"locations": []}')
+        output_text = output.get_data(as_text=True)
+        self.assertEqual(output_text, '{"locations": []}')
 
         self.__setup_db()
 
         output = self.app.get('/api/locations/')
         self.assertEqual(output.status_code, 200)
-        self.assertEqual(output.data, '{"locations": ["EMEA", "NA"]}')
+        output_text = output.get_data(as_text=True)
+        self.assertEqual(output_text, '{"locations": ["EMEA", "NA"]}')
 
         output = self.app.get('/api/locations/?callback="abcd"')
         self.assertEqual(output.status_code, 200)
-        self.assertEqual(
-            output.data,
-            '"abcd"([\'{"locations": ["EMEA", "NA"]}\']);')
+        output_text = output.get_data(as_text=True)
+        if six.PY3:
+            self.assertEqual(
+                output_text, '"abcd"([b\'{"locations": ["EMEA", "NA"]}\']);')
+        else:
+            self.assertEqual(
+                output_text, '"abcd"([\'{"locations": ["EMEA", "NA"]}\']);')
 
     def test_api_search_locations(self):
         """ Test the api_search_locations function. """
         output = self.app.get('/api/locations/search/')
         self.assertEqual(output.status_code, 400)
+        output_text = output.get_data(as_text=True)
         self.assertEqual(
-            output.data,
+            output_text,
             '{"error": "no keyword provided"}')
 
         self.__setup_db()
 
         output = self.app.get('/api/locations/search/?keyword=ME')
         self.assertEqual(output.status_code, 200)
-        self.assertEqual(output.data, '{"locations": ["EMEA"]}')
+        output_text = output.get_data(as_text=True)
+        self.assertEqual(output_text, '{"locations": ["EMEA"]}')
 
         output = self.app.get(
             '/api/locations/search/?keyword=ME&callback="abcd"')
         self.assertEqual(output.status_code, 200)
-        self.assertEqual(
-            output.data,
-            '"abcd"([\'{"locations": ["EMEA"]}\']);')
+        output_text = output.get_data(as_text=True)
+        if six.PY3:
+            self.assertEqual(
+                output_text, '"abcd"([b\'{"locations": ["EMEA"]}\']);')
+        else:
+            self.assertEqual(
+                output_text, '"abcd"([\'{"locations": ["EMEA"]}\']);')
 
 
 if __name__ == '__main__':
diff --git a/tests/test_flask_extras.py b/tests/test_flask_extras.py
index 63eae87..0ed8aad 100644
--- a/tests/test_flask_extras.py
+++ b/tests/test_flask_extras.py
@@ -27,9 +27,7 @@
  fedocal's flask application tests script
  - for special corner case to test
 """
-
-__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4']
-import pkg_resources
+from __future__ import unicode_literals, absolute_import, print_function
 
 import flask
 import logging
@@ -104,15 +102,16 @@ class ExtrasFlasktests(Modeltests):
         with user_set(fedocal.APP, user):
             output = self.app.get('/meeting/edit/1/')
             self.assertEqual(output.status_code, 200)
+            output_text = output.get_data(as_text=True)
 
             next_date = TODAY + timedelta(days=14)
             if date.today() <= TODAY:
                 next_date = TODAY
 
             # If no date is specified, it returns the next occurence
-            self.assertTrue(
+            self.assertIn(
                 '<input id="meeting_date" name="meeting_date" type="text" '
-                'value="%s">' % (next_date) in output.data
+                'value="%s">' % (next_date), output_text
             )
 
             # If a date in the future is specified, return the next occurence
@@ -121,11 +120,12 @@ class ExtrasFlasktests(Modeltests):
                 TODAY + timedelta(days=20))
             output2 = self.app.get(url)
             self.assertEqual(output2.status_code, 200)
+            output2_text = output2.get_data(as_text=True)
 
-            self.assertTrue(
+            self.assertIn(
                 '<input id="meeting_date" name="meeting_date" type="text" '
-                'value="%s">' % (TODAY + timedelta(days=28))
-                in output2.data
+                'value="%s">' % (TODAY + timedelta(days=28)),
+                output2_text
             )
 
             # If an exact date in the future is specified, return that date
@@ -133,20 +133,21 @@ class ExtrasFlasktests(Modeltests):
                 TODAY + timedelta(days=14))
             output2 = self.app.get(url)
             self.assertEqual(output2.status_code, 200)
+            output2_text = output2.get_data(as_text=True)
 
-            self.assertTrue(
+            self.assertIn(
                 '<input id="meeting_date" name="meeting_date" type="text" '
-                'value="%s">' % (TODAY + timedelta(days=14)) in output2.data
+                'value="%s">' % (TODAY + timedelta(days=14)), output2_text
             )
 
             # If an old date in the future is specified, return the first date
             output2 = self.app.get('/meeting/edit/1/?from_date=2000-01-01')
             self.assertEqual(output2.status_code, 200)
+            output2_text = output2.get_data(as_text=True)
 
-            self.assertTrue(
+            self.assertIn(
                 '<input id="meeting_date" name="meeting_date" type="text" '
-                'value="%s">' % (TODAY)
-                in output2.data
+                'value="%s">' % (TODAY), output2_text
             )
 
     @flask10_only
@@ -176,13 +177,14 @@ class ExtrasFlasktests(Modeltests):
         with user_set(fedocal.APP, user):
             output = self.app.get('/meeting/delete/1/')
             self.assertEqual(output.status_code, 200)
+            output_text = output.get_data(as_text=True)
 
             next_date = TODAY + timedelta(days=14)
             if date.today() <= TODAY:
                 next_date = TODAY
 
             # If no date is specified, it returns the next occurence
-            self.assertTrue('<li>Date: %s</li>' % next_date in output.data)
+            self.assertIn('<li>Date: %s</li>' % next_date, output_text)
 
             # If a date in the future is specified, return the next occurence
             # for this date
@@ -190,10 +192,11 @@ class ExtrasFlasktests(Modeltests):
                 TODAY + timedelta(days=20))
             output2 = self.app.get(url)
             self.assertEqual(output2.status_code, 200)
+            output_text = output2.get_data(as_text=True)
 
-            self.assertTrue(
-                '<li>Date: %s</li>' % (TODAY + timedelta(days=28))
-                in output2.data
+            self.assertIn(
+                '<li>Date: %s</li>' % (TODAY + timedelta(days=28)),
+                output_text
             )
 
             # If an exact date in the future is specified, return that date
@@ -201,17 +204,20 @@ class ExtrasFlasktests(Modeltests):
                 TODAY + timedelta(days=14))
             output2 = self.app.get(url)
             self.assertEqual(output2.status_code, 200)
+            output_text = output2.get_data(as_text=True)
 
-            self.assertTrue('<li>Date: %s</li>' % next_date in output.data)
+            self.assertIn('<li>Date: %s</li>' % next_date, output_text)
 
             # If an old date in the future is specified, return the first date
             output2 = self.app.get('/meeting/delete/1/?from_date=2000-01-01')
             self.assertEqual(output2.status_code, 200)
+            output_text = output2.get_data(as_text=True)
 
             self.assertTrue(
-                '<li>Date: %s</li>' % (TODAY) in output2.data
+                '<li>Date: %s</li>' % (TODAY), output_text
             )
 
+
 if __name__ == '__main__':
     SUITE = unittest.TestLoader().loadTestsFromTestCase(ExtrasFlasktests)
     unittest.TextTestRunner(verbosity=2).run(SUITE)
diff --git a/tests/test_meeting.py b/tests/test_meeting.py
index f41a90c..4a52023 100644
--- a/tests/test_meeting.py
+++ b/tests/test_meeting.py
@@ -26,9 +26,7 @@
 
  fedocal.model test script
 """
-
-__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4']
-import pkg_resources
+from __future__ import unicode_literals, absolute_import, print_function
 
 import unittest
 import sys
@@ -41,8 +39,8 @@ sys.path.insert(0, os.path.join(os.path.dirname(
     os.path.abspath(__file__)), '..'))
 
 from fedocal.fedocallib import model
-from tests import Modeltests, TODAY
-from test_calendar import Calendartests
+from . import Modeltests, TODAY
+from .test_calendar import Calendartests
 
 
 # pylint: disable=R0904
diff --git a/tests/test_reminder.py b/tests/test_reminder.py
index e66bc55..23ce5aa 100644
--- a/tests/test_reminder.py
+++ b/tests/test_reminder.py
@@ -26,9 +26,7 @@
 
  fedocal.model test script
 """
-
-__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4']
-import pkg_resources
+from __future__ import unicode_literals, absolute_import, print_function
 
 import unittest
 import sys
diff --git a/tests/test_week.py b/tests/test_week.py
index 98cde55..016e0d5 100644
--- a/tests/test_week.py
+++ b/tests/test_week.py
@@ -26,9 +26,7 @@
 
  fedocal.model test script
 """
-
-__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4']
-import pkg_resources
+from __future__ import unicode_literals, absolute_import, print_function
 
 import unittest
 import sys
@@ -44,7 +42,7 @@ from fedocal.fedocallib import week
 from fedocal.fedocallib import exceptions
 
 from tests import Modeltests
-from test_meeting import Meetingtests, TODAY
+from .test_meeting import Meetingtests, TODAY
 
 
 # pylint: disable=C0103

From b4c175b1ab67cb08722cdfc64f8b4e89433db86d Mon Sep 17 00:00:00 2001
From: Pierre-Yves Chibon <pingou@pingoured.fr>
Date: Dec 21 2018 14:30:27 +0000
Subject: [PATCH 2/3] Make the running the test under py3 by default


Signed-off-by: Pierre-Yves Chibon <pingou@pingoured.fr>

---

diff --git a/nosetests b/nosetests
index 2f5271b..f6d948f 100755
--- a/nosetests
+++ b/nosetests
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # EASY-INSTALL-ENTRY-SCRIPT: 'nose==0.10.4','console_scripts','nosetests'
 __requires__ = ['nose>=0.10.4', 'SQLAlchemy >= 0.7', 'jinja2 >= 2.4']
 import sys

From 6fb63088376e996250946708e59a349c956598d7 Mon Sep 17 00:00:00 2001
From: Pierre-Yves Chibon <pingou@pingoured.fr>
Date: Dec 21 2018 14:30:38 +0000
Subject: [PATCH 3/3] Start adding some logging to fedocal


Signed-off-by: Pierre-Yves Chibon <pingou@pingoured.fr>

---

diff --git a/fedocal/fedocallib/__init__.py b/fedocal/fedocallib/__init__.py
index 9f4f703..660f9a7 100644
--- a/fedocal/fedocallib/__init__.py
+++ b/fedocal/fedocallib/__init__.py
@@ -16,6 +16,7 @@ license.
 from __future__ import unicode_literals, absolute_import, print_function
 
 import copy
+import logging
 import operator
 from datetime import datetime
 from datetime import date
@@ -43,6 +44,8 @@ from fedocal.fedocallib.fedora_calendar import FedocalCalendar
 
 from fedocal.fedocal_babel import gettext
 
+_log = logging.getLogger(__name__)
+
 
 HOURS = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09',
          '10', '11', '12', '13', '14', '15', '16', '17', '18', '19',
@@ -1166,6 +1169,7 @@ def add_vcal_file(session, calendar, stream, fas_user, admin=False):
     """ Add the meetings from the iCalendar stream provided into the calendar
     specified.
     """
+    _log.info('Uploading a vCal file')
     # Build a dict with all the common timezones storing for each their
     # localize name and their offset (ie: CEST 2:00:00)
     timezone_lookup = dict()
@@ -1240,6 +1244,11 @@ def add_vcal_file(session, calendar, stream, fas_user, admin=False):
             meeting_time_stop = meeting_date_end.time()
             meeting_date_end = meeting_date_end.date()
 
+        _log.info('Add meeting: {} - Start: {}:{} - End:   {}:{}'.format(
+            meeting_name, meeting_date, meeting_time_start,
+            meeting_date_end, meeting_time_stop
+        ))
+
         add_meeting(
             session,
             calendarobj=calendar,

