Projet

Général

Profil

0001-add-compatibility-with-python-3-25642.patch

Frédéric Péters, 12 août 2018 17:48

Télécharger (29,5 ko)

Voir les différences:

Subject: [PATCH] add compatibility with python 3 (#25642)

 fargo/fargo/api_fields.py                     |  2 +-
 fargo/fargo/api_views.py                      |  2 +-
 .../0001_squashed_0017_auto_20180331_1532.py  |  2 +-
 fargo/fargo/models.py                         | 15 ++++++---
 fargo/fargo/views.py                          |  4 +--
 fargo/oauth2/authentication.py                |  2 +-
 .../commands/oauth2-put-document.py           |  2 +-
 .../0001_squashed_0005_auto_20180331_1532.py  |  2 +-
 fargo/oauth2/models.py                        |  4 ++-
 fargo/oauth2/utils.py                         | 10 +++---
 fargo/oauth2/views.py                         |  5 ++-
 fargo/settings.py                             |  2 +-
 fargo/utils.py                                |  4 +--
 tests/conftest.py                             |  6 ++--
 tests/test_api.py                             | 24 +++++++-------
 tests/test_commands.py                        |  4 +--
 tests/test_manager.py                         |  2 +-
 tests/test_oauth2.py                          | 29 +++++++++--------
 tests/test_public.py                          | 32 +++++++++----------
 tox.ini                                       |  3 +-
 20 files changed, 83 insertions(+), 73 deletions(-)
fargo/fargo/api_fields.py
33 33
                raise api_errors.APIError('NOT_BASE64')
34 34
            max_size = self.get_max_size()
35 35
            if max_size and len(content) > self.get_max_size():
36
                raise api_errors.APIError('TOO_BIG', limit=self.get_max_size())
36
                raise api_errors.APIError('TOO_BIG', limit=str(self.get_max_size()))
37 37
            data = ContentFile(content, name=name)
38 38
        else:
39 39
            raise api_errors.APIError('NOT_STRING')
fargo/fargo/api_views.py
99 99
        user = data['user']
100 100
        if (Document.objects.used_space(user) + data['file_b64_content'].size
101 101
                > settings.FARGO_MAX_DOCUMENT_BOX_SIZE):
102
            raise api_errors.APIError('BOX_IS_FULL', limit=settings.FARGO_MAX_DOCUMENT_BOX_SIZE)
102
            raise api_errors.APIError('BOX_IS_FULL', limit=str(settings.FARGO_MAX_DOCUMENT_BOX_SIZE))
103 103
        return data
104 104

  
105 105

  
fargo/fargo/migrations/0001_squashed_0017_auto_20180331_1532.py
12 12

  
13 13
class Migration(migrations.Migration):
14 14

  
15
    replaces = [(b'fargo', '0001_initial'), (b'fargo', '0002_auto_20150818_2117'), (b'fargo', '0003_auto_20150924_1056'), (b'fargo', '0004_auto_20160212_0936'), (b'fargo', '0005_auto_20160312_1809'), (b'fargo', '0006_fill_new_columns'), (b'fargo', '0007_auto_20160312_1816'), (b'fargo', '0008_validation_origin'), (b'fargo', '0009_auto_20160326_2104'), (b'fargo', '0010_auto_20160413_0809'), (b'fargo', '0011_userdocument_deletable_by_user'), (b'fargo', '0012_auto_20161124_0626'), (b'fargo', '0013_document_mime_type'), (b'fargo', '0014_auto_20171016_0854'), (b'fargo', '0015_document_creation_date'), (b'fargo', '0016_auto_20180330_2248'), (b'fargo', '0017_auto_20180331_1532')]
15
    replaces = [('fargo', '0001_initial'), ('fargo', '0002_auto_20150818_2117'), ('fargo', '0003_auto_20150924_1056'), ('fargo', '0004_auto_20160212_0936'), ('fargo', '0005_auto_20160312_1809'), ('fargo', '0006_fill_new_columns'), ('fargo', '0007_auto_20160312_1816'), ('fargo', '0008_validation_origin'), ('fargo', '0009_auto_20160326_2104'), ('fargo', '0010_auto_20160413_0809'), ('fargo', '0011_userdocument_deletable_by_user'), ('fargo', '0012_auto_20161124_0626'), ('fargo', '0013_document_mime_type'), ('fargo', '0014_auto_20171016_0854'), ('fargo', '0015_document_creation_date'), ('fargo', '0016_auto_20180330_2248'), ('fargo', '0017_auto_20180331_1532')]
16 16

  
17 17
    initial = True
18 18

  
fargo/fargo/models.py
8 8
from django.conf import settings
9 9
from django.core.urlresolvers import reverse
10 10
from django.db import models
11
from django.utils.encoding import python_2_unicode_compatible
11 12
from django.utils.translation import ugettext_lazy as _
13
from django.utils.encoding import force_text
12 14
from django.utils.text import slugify
13 15
from django.utils.http import urlquote
14 16
from django.utils.html import format_html
......
24 26
from . import utils, managers
25 27

  
26 28

  
29
@python_2_unicode_compatible
27 30
class Origin(models.Model):
28 31
    label = models.CharField(_('Label'), max_length=80)
29 32
    slug = models.SlugField(_('Slug'))
......
33 36
            self.slug = slugify(self.label)
34 37
        return super(Origin, self).save(*args, **kwargs)
35 38

  
36
    def __unicode__(self):
39
    def __str__(self):
37 40
        return self.label
38 41

  
39 42

  
43
@python_2_unicode_compatible
40 44
class UserDocument(models.Model):
41 45
    '''Document uploaded by an user or an agent'''
42 46
    user = models.ForeignKey(
......
82 86
    def filename_encoded(self):
83 87
        return urlquote(self.filename, safe='')
84 88

  
85
    def __unicode__(self):
89
    def __str__(self):
86 90
        return self.title or self.filename
87 91

  
88 92
    def get_download_url(self):
......
105 109
                re.sub('[/\.+-]', '-', self.document.mime_type))
106 110

  
107 111

  
112
@python_2_unicode_compatible
108 113
class Validation(models.Model):
109 114
    '''Validation of a document as special kind for an user,
110 115
       the data field contains metadata extracted from the document.
......
140 145
        template = self.document_type_schema.get('display_template', '')
141 146
        if template:
142 147
            try:
143
                return unicode(template.format(**self.data))
148
                return force_text(template.format(**self.data))
144 149
            except KeyError:
145 150
                pass
146 151
        l = []
......
150 155
                         'label': meta_field['label'],
151 156
                         'value': self.data.get(meta_field['varname'], ''),
152 157
                     })
153
        return unicode(u'; '.join(l))
158
        return force_text(u'; '.join(l))
154 159
    display.short_description = _('description')
155 160

  
156 161
    @property
......
161 166
            except UserDocument.DoesNotExist:
162 167
                pass
163 168

  
164
    def __unicode__(self):
169
    def __str__(self):
165 170
        return self.display()
166 171

  
167 172

  
fargo/fargo/views.py
1
import urllib
2 1
import logging
3 2
from json import dumps
4 3
from copy import deepcopy
......
16 15
from django.contrib.auth import get_user_model, REDIRECT_FIELD_NAME
17 16
from django.contrib.auth import logout as auth_logout
18 17
from django.contrib.auth import views as auth_views
18
from django.utils.http import quote
19 19
from django.utils.translation import ugettext as _
20 20
from django.utils.decorators import method_decorator
21 21
from django.conf import settings
......
262 262
        if not 'next' in request.GET:
263 263
            return HttpResponseRedirect(resolve_url('mellon_login'))
264 264
        return HttpResponseRedirect(resolve_url('mellon_login') + '?next='
265
                                    + urllib.quote(request.GET.get('next')))
265
                                    + quote(request.GET.get('next')))
266 266
    return auth_views.login(request, *args, **kwargs)
267 267

  
268 268

  
fargo/oauth2/authentication.py
14 14
# You should have received a copy of the GNU Affero General Public License
15 15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 16

  
17
import urlparse
18 17
import logging
19 18

  
20 19
import requests
21 20

  
22 21
from django.conf import settings
23 22

  
23
from django.utils.six.moves.urllib import parse as urlparse
24 24
from django.utils.translation import ugettext_lazy as _
25 25

  
26 26
from rest_framework.authentication import BasicAuthentication
fargo/oauth2/management/commands/oauth2-put-document.py
20 20
    def handle(self, redirect_uri, paths, client_id, **options):
21 21
        client = OAuth2Client.objects.get(id=client_id)
22 22
        for path in paths:
23
            with open(path) as file_object:
23
            with open(path, 'rb') as file_object:
24 24
                filename = os.path.basename(path)
25 25
                f = ContentFile(file_object.read(), name=filename)
26 26
                document = Document.objects.get_by_file(f)
fargo/oauth2/migrations/0001_squashed_0005_auto_20180331_1532.py
9 9

  
10 10
class Migration(migrations.Migration):
11 11

  
12
    replaces = [(b'oauth2', '0001_initial'), (b'oauth2', '0002_auto_20180321_2343'), (b'oauth2', '0003_auto_20180322_1016'), (b'oauth2', '0004_auto_20180326_1330'), (b'oauth2', '0005_auto_20180331_1532')]
12
    replaces = [('oauth2', '0001_initial'), ('oauth2', '0002_auto_20180321_2343'), ('oauth2', '0003_auto_20180322_1016'), ('oauth2', '0004_auto_20180326_1330'), ('oauth2', '0005_auto_20180331_1532')]
13 13

  
14 14
    initial = True
15 15

  
fargo/oauth2/models.py
21 21
from django.core.exceptions import ValidationError
22 22
from django.core.validators import URLValidator
23 23
from django.db import models
24
from django.utils.encoding import python_2_unicode_compatible
24 25
from django.utils.translation import ugettext_lazy as _
25 26
from django.db.models.query import QuerySet
26 27
from django.utils.timezone import now
......
46 47
        raise ValidationError(errors)
47 48

  
48 49

  
50
@python_2_unicode_compatible
49 51
class OAuth2Client(models.Model):
50 52
    client_name = models.CharField(max_length=255)
51 53
    redirect_uris = models.TextField(
......
63 65
    def check_redirect_uri(self, redirect_uri):
64 66
        return redirect_uri in self.redirect_uris.strip().split()
65 67

  
66
    def __unicode__(self):
68
    def __str__(self):
67 69
        return self.client_name
68 70

  
69 71
    class Meta:
fargo/oauth2/utils.py
1 1
import cgi
2
from urllib import unquote
3 2

  
3
from django.utils import six
4
from django.utils.http import unquote
4 5
from django.utils.timezone import now
5 6
from django.conf import settings
6 7

  
......
35 36
        return None, 'wrong disposition type: attachment expected'
36 37
    if 'filename*' in filename:
37 38
        encode, country, name = filename['filename*'].split("'")
38

  
39
        if six.PY3:
40
            return (unquote(name, encode), None)
39 41
        # check accepted charset from rfc 5987
40 42
        if encode == 'UTF-8':
41
            return unquote(name.decode('utf8')), None
43
            return unquote(name).decode('utf8'), None
42 44
        elif encode == 'ISO-8859-1':
43
            return unquote(name.decode('iso-8859-1')), None
45
            return unquote(name).decode('iso-8859-1'), None
44 46
        else:
45 47
            return None, 'unknown encoding: UTF-8 or ISO-8859-1 allowed'
46 48
    elif 'filename' in filename:
fargo/oauth2/views.py
16 16

  
17 17
import logging
18 18

  
19
from urllib import quote
20

  
21 19
from django.shortcuts import get_object_or_404
20
from django.utils.http import quote
22 21
from django.utils.translation import ugettext as _
23 22
from django.utils.timezone import now
24 23
from django.core.files.base import ContentFile
......
154 153
                            content_type='application/octet-stream')
155 154

  
156 155
    filename = user_document.filename
157
    ascii_filename = filename.encode('ascii', 'replace')
156
    ascii_filename = filename.encode('ascii', 'replace').decode()
158 157
    percent_encoded_filename = quote(filename.encode('utf8'), safe='')
159 158
    response['Content-Disposition'] = 'attachment; filename="%s"; filename*=UTF-8\'\'%s' % (ascii_filename,
160 159
                                                                                            percent_encoded_filename)
fargo/settings.py
246 246
                                         'local_settings.py'))
247 247

  
248 248
if os.path.exists(local_settings_file):
249
    execfile(local_settings_file)
249
    exec(open(local_settings_file).read())
fargo/utils.py
1
import urlparse
2 1
from django.utils.http import urlencode
2
from django.utils.six.moves.urllib import parse as urlparse
3 3

  
4 4

  
5 5
def make_url(__url, **kwargs):
6 6
    request = kwargs.pop('request', None)
7 7
    parsed = urlparse.urlparse(__url)
8 8
    query = urlparse.parse_qs(parsed.query)
9
    for key, value in kwargs.iteritems():
9
    for key, value in kwargs.items():
10 10
        if value is not None:
11 11
            query[key] = value
12 12
    parsed = parsed[:4] + (urlencode(query),) + parsed[5:]
tests/conftest.py
1
# -*- coding: utf-8 -*-
2

  
1 3
import logging
2 4
import pytest
3 5
import django_webtest
......
96 98

  
97 99
@pytest.fixture
98 100
def user_doc(document, john_doe):
99
    return UserDocument.objects.create(user=john_doe, document=document, filename='Baudelaire.txt')
100

  
101

  
101
    return UserDocument.objects.create(user=john_doe, document=document, filename='éléphant.txt')
tests/test_api.py
65 65
            == set(['origin', 'file_b64_content']))
66 66
    data.update({
67 67
        'origin': 'wcs',
68
        'file_b64_content': base64.b64encode('coin'),
68
        'file_b64_content': base64.b64encode(b'coin').decode(),
69 69
        'file_name': 'monfichier.pdf',
70 70
    })
71 71
    response = app.post_json(url, params=data, status=200)
......
77 77
    assert models.UserDocument.objects.get().user == john_doe
78 78
    assert models.UserDocument.objects.get().deletable_by_user == True
79 79
    assert models.Document.objects.count() == 1
80
    assert models.Document.objects.get().content.read() == 'coin'
80
    assert models.Document.objects.get().content.read() == b'coin'
81 81
    assert (models.UserDocument.objects.get().document
82 82
            == models.Document.objects.get())
83 83
    assert (models.UserDocument.objects.get().origin
84 84
            == models.Origin.objects.get())
85 85

  
86
    data['file_b64_content'] = base64.b64encode('coin2')
86
    data['file_b64_content'] = base64.b64encode(b'coin2').decode()
87 87
    data['deletable_by_user'] = False
88 88
    response = app.post_json(url, params=data, status=200)
89 89
    assert response.json['result'] == 1
......
91 91
    assert models.UserDocument.objects.count() == 2 # new document
92 92
    assert models.UserDocument.objects.filter(deletable_by_user=False).count() == 1
93 93

  
94
    data['file_b64_content'] = base64.b64encode('coin3')
94
    data['file_b64_content'] = base64.b64encode(b'coin3').decode()
95 95
    data['deletable_by_user'] = True
96 96
    response = app.post_json(url, params=data, status=200)
97 97
    assert response.json['result'] == 1
......
99 99
    assert models.UserDocument.objects.filter(deletable_by_user=True).count() == 2
100 100

  
101 101
    # same document
102
    data['file_b64_content'] = base64.b64encode('coin3')
102
    data['file_b64_content'] = base64.b64encode(b'coin3').decode()
103 103
    data['deletable_by_user'] = True
104 104
    response = app.post_json(url, params=data, status=400)
105 105
    assert response.json['result'] == 0
......
114 114
    data = {
115 115
        'user_email': john_doe.email,
116 116
        'origin': 'wcs',
117
        'file_b64_content': base64.b64encode('coin'),
117
        'file_b64_content': base64.b64encode(b'coin').decode(),
118 118
        'file_name': 'monfichier.pdf',
119 119
    }
120 120
    response = app.post_json(url, params=data, status=400)
121 121
    assert response.json['result'] == 0
122
    assert response.json['errors'].keys() == ['file_b64_content']
122
    assert list(response.json['errors'].keys()) == ['file_b64_content']
123 123
    assert response.json['errors']['file_b64_content'][0]['code'] == 'too-big'
124
    assert response.json['errors']['file_b64_content'][0]['limit'] == 1
124
    assert response.json['errors']['file_b64_content'][0]['limit'] == '1'
125 125

  
126 126

  
127 127
def test_push_document_max_document_box_size(app, private_settings, admin_user, john_doe):
......
131 131
    data = {
132 132
        'user_email': john_doe.email,
133 133
        'origin': 'wcs',
134
        'file_b64_content': base64.b64encode('coin'),
134
        'file_b64_content': base64.b64encode(b'coin').decode(),
135 135
        'file_name': 'monfichier.pdf',
136 136
    }
137 137
    response = app.post_json(url, params=data, status=200)
......
139 139
    assert models.Document.objects.count() == 1
140 140
    response = app.post_json(url, params=data, status=400)
141 141
    assert response.json['result'] == 0
142
    assert response.json['errors'].keys() == ['__all__']
142
    assert list(response.json['errors'].keys()) == ['__all__']
143 143
    assert response.json['errors']['__all__'][0]['code'] == 'box-is-full'
144
    assert response.json['errors']['__all__'][0]['limit'] == 4
144
    assert response.json['errors']['__all__'][0]['limit'] == '4'
145 145

  
146 146

  
147 147
def test_push_document_slashed_name(app, admin_user, john_doe):
......
150 150
    data = {
151 151
        'user_email': john_doe.email,
152 152
        'origin': 'wcs',
153
        'file_b64_content': base64.b64encode('whatever'),
153
        'file_b64_content': base64.b64encode(b'whatever').decode(),
154 154
        'file_name': 'monfichier 18/06/2017.pdf',
155 155
    }
156 156
    response = app.post_json(url, params=data, status=200)
tests/test_commands.py
13 13

  
14 14
    client = OAuth2Client.objects.create(client_name='c', redirect_uris='')
15 15

  
16
    foo = Document.objects.create(content=ContentFile('foo', name='foo.txt'))
17
    bar = Document.objects.create(content=ContentFile('bar', name='bar.txt'))
16
    foo = Document.objects.create(content=ContentFile(b'foo', name='foo.txt'))
17
    bar = Document.objects.create(content=ContentFile(b'bar', name='bar.txt'))
18 18
    UserDocument.objects.create(user=john_doe,
19 19
                                document=foo,
20 20
                                filename='foo.txt',
tests/test_manager.py
21 21
    return app
22 22

  
23 23
def test_document_delete(app):
24
    f = ContentFile('A test file, ez pz.', 'test_file.txt')
24
    f = ContentFile(b'A test file, ez pz.', 'test_file.txt')
25 25
    doc = Document.objects.get_by_file(f)
26 26
    file_path = doc.content.path
27 27
    assert os.path.isfile(file_path)
tests/test_oauth2.py
1
# -*- coding: utf-8 -*-
2

  
1 3
import os
2 4
import json
3 5
import mock
4 6
import pytest
5
from urllib import quote
6
import urlparse
7 7

  
8 8
from django.core.urlresolvers import reverse
9
from django.utils.http import urlencode
10 9
from django.core.management import call_command
10
from django.utils.http import quote, urlencode
11
from django.utils.six.moves.urllib import parse as urlparse
11 12

  
12 13
from fargo.oauth2.models import OAuth2Client, OAuth2Authorize, OAuth2TempFile
13 14
from fargo.fargo.models import UserDocument
......
44 45
    }
45 46
    # test missing redirect_uri
46 47
    resp = app.get(url, params={}, status=400)
47
    assert resp.content == 'missing redirect_uri parameter'
48
    assert resp.text == 'missing redirect_uri parameter'
48 49
    # test missing client id
49 50
    params['redirect_uri'] = 'https://toto.example.com'
50 51
    resp = app.get(url, params=params, status=302)
......
65 66
    assert resp.status_code == 200
66 67
    assert len(resp.forms[0]['document'].options) == 2
67 68
    options = resp.forms[0]['document'].options
68
    assert 'Baudelaire.txt' in options[1]
69
    assert u'éléphant.txt' in options[1]
69 70

  
70 71
    resp.forms[0]['document'].select(options[1][0])
71 72
    resp = resp.forms[0].submit()
......
97 98
    assert 'Content-disposition' in resp.headers
98 99
    content_disposition = resp.content_disposition.replace(' ', '').split(';')
99 100
    assert content_disposition[0] == 'attachment'
100
    assert content_disposition[1] == 'filename="Baudelaire.txt"'
101
    assert content_disposition[2] == 'filename*=UTF-8\'\'Baudelaire.txt'
101
    assert content_disposition[1] == 'filename="?l?phant.txt"'
102
    assert content_disposition[2] == 'filename*=UTF-8\'\'%C3%A9l%C3%A9phant.txt'
102 103

  
103 104

  
104 105
def test_put_document(app, john_doe, oauth2_client):
......
111 112

  
112 113
    app.authorization = ('Basic', (str(oauth2_client.client_id), str(oauth2_client.client_secret)))
113 114
    resp = app.post(url, params=data, status=400)
114
    assert 'missing content-disposition header' in resp.content
115
    assert 'missing content-disposition header' in resp.text
115 116

  
116
    filename = 'Baudelaire.txt'.encode('ascii', 'replace')
117
    percent_encode_filename = quote(filename.encode('utf8'), safe='')
117
    filename = 'éléphant.txt'
118
    percent_encode_filename = quote(filename, safe='')
118 119
    headers = {
119 120
        'Content-disposition': 'attachment; filename="%s"; filename*=UTF-8\'\'%s' % (filename, percent_encode_filename)
120 121
    }
......
145 146
    assert OAuth2TempFile.objects.count() == 1
146 147
    assert UserDocument.objects.count() == 1
147 148
    assert OAuth2TempFile.objects.get().document == UserDocument.objects.get().document
148
    assert UserDocument.objects.filter(user=john_doe, document=doc.document, filename='Baudelaire.txt').exists()
149
    assert UserDocument.objects.filter(user=john_doe, document=doc.document, filename=u'éléphant.txt').exists()
149 150

  
150 151

  
151 152
def test_confirm_put_document_file_exception(app, oauth2_client, john_doe, user_doc):
......
158 159
    url = reverse('oauth2-put-document-authorize', kwargs={'pk': 'fakemofo'})
159 160
    url += '?%s' % urlencode({'redirect_uri': 'https://example.com'})
160 161
    resp = app.get(url)
161
    assert 'The document has not been uploaded' in resp.content
162
    assert 'The document has not been uploaded' in resp.text
162 163

  
163 164
    url = reverse('oauth2-put-document-authorize', kwargs={'pk': oauth_tmp_file.pk})
164 165
    url += '?%s' % urlencode({'redirect_uri': 'https://example.com'})
165 166
    resp = app.get(url)
166
    assert 'This document is already in your portfolio' in resp.content
167
    assert 'This document is already in your portfolio' in resp.text
167 168

  
168 169

  
169 170
@mock.patch('fargo.oauth2.authentication.requests.post')
......
180 181
    params['redirect_uri'] = 'https://example.com'
181 182
    resp = app.get(url, params=params)
182 183
    options = resp.forms[0]['document'].options
183
    assert 'Baudelaire.txt' in options[1]
184
    assert u'éléphant.txt' in options[1]
184 185
    resp.forms[0]['document'].select(options[1][0])
185 186
    resp = resp.forms[0].submit()
186 187
    auth = OAuth2Authorize.objects.filter(user_document__user=john_doe)[0]
tests/test_public.py
2 2

  
3 3
from webtest import Upload
4 4
import pytest
5
import urlparse
6 5

  
7 6
from django.core.urlresolvers import reverse
7
from django.utils.six.moves.urllib import parse as urlparse
8 8

  
9 9
try:
10 10
    import magic
......
26 26
    login(app, user=john_doe)
27 27
    response1 = app.get('/')
28 28
    form = response1.form
29
    form['content'] = Upload('monfichier.pdf', 'coin', 'application/pdf')
29
    form['content'] = Upload('monfichier.pdf', b'coin', 'application/pdf')
30 30
    response2 = form.submit().follow()
31
    assert 'monfichier.pdf' in response2.content
31
    assert 'monfichier.pdf' in response2.text
32 32
    if magic is not None:
33 33
        assert UserDocument.objects.get(filename='monfichier.pdf').document.mime_type == 'text/plain'
34
        assert ' mime-text ' in response2.content
35
        assert ' mime-text-plain' in response2.content
34
        assert ' mime-text ' in response2.text
35
        assert ' mime-text-plain' in response2.text
36 36

  
37 37
    UserDocument.objects.all().delete()
38 38

  
39 39
    response1 = app.get('/')
40 40
    form = response1.form
41
    form['content'] = Upload('monfichier.pdf', '%PDF-1.4 ...', 'application/pdf')
41
    form['content'] = Upload('monfichier.pdf', b'%PDF-1.4 ...', 'application/pdf')
42 42
    response2 = form.submit().follow()
43
    assert 'monfichier.pdf' in response2.content
44
    assert '12 bytes' in response2.content
43
    assert 'monfichier.pdf' in response2.text
44
    assert u'12 bytes' in response2.text
45 45
    if magic is not None:
46 46
        assert UserDocument.objects.get(filename='monfichier.pdf').document.mime_type == 'application/pdf'
47
        assert ' mime-application ' in response2.content
48
        assert ' mime-application-pdf' in response2.content
47
        assert ' mime-application ' in response2.text
48
        assert ' mime-application-pdf' in response2.text
49 49

  
50 50

  
51 51
def test_upload_max_size(app, private_settings, john_doe):
......
53 53
    login(app, user=john_doe)
54 54
    response1 = app.get('/')
55 55
    form = response1.form
56
    form['content'] = Upload('monfichier.pdf', 'coin', 'application/pdf')
56
    form['content'] = Upload('monfichier.pdf', b'coin', 'application/pdf')
57 57
    response2 = form.submit()
58 58
    assert response2.status_code == 200
59
    assert 'Uploaded file is too big' in response2.content
59
    assert 'Uploaded file is too big' in response2.text
60 60

  
61 61

  
62 62
def test_upload_max_document_box_size(app, private_settings, john_doe):
......
64 64
    login(app, user=john_doe)
65 65
    response1 = app.get('/')
66 66
    form = response1.form
67
    form['content'] = Upload('monfichier.pdf', 'coin', 'application/pdf')
67
    form['content'] = Upload('monfichier.pdf', b'coin', 'application/pdf')
68 68
    response2 = form.submit().follow()
69
    assert 'monfichier.pdf' in response2.content
69
    assert 'monfichier.pdf' in response2.text
70 70
    response1 = app.get('/')
71 71
    form = response1.forms['send-file']
72
    form['content'] = Upload('monfichier.pdf', 'coin', 'application/pdf')
72
    form['content'] = Upload('monfichier.pdf', b'coin', 'application/pdf')
73 73
    response2 = form.submit()
74 74
    assert response2.status_code == 200
75
    assert 'Your document box is full (limit is 4)' in response2.content
75
    assert 'Your document box is full (limit is 4)' in response2.text
76 76

  
77 77

  
78 78
def test_pick(app, private_settings, john_doe, user_doc):
tox.ini
1 1
[tox]
2 2
toxworkdir = {env:TMPDIR:/tmp}/tox-{env:USER}/fargo/
3
envlist = coverage-dj18-sqlite,coverage-dj111-sqlite,coverage-dj18-pg,coverage-dj111-pg
3
envlist = py2-coverage-dj18-sqlite,py2-coverage-dj111-sqlite,py2-coverage-dj18-pg,{py2,py3}-coverage-dj111-pg
4 4

  
5 5
[testenv]
6 6
usedevelop = True
......
27 27
        django-webtest<1.9.3
28 28
        WebTest
29 29
        djangorestframework>=3.3,<3.4
30
        mock
30 31
commands =
31 32
        py.test {env:COVERAGE:} {posargs:--random --junit-xml=junit-{envname}.xml tests}
32 33
        coverage: mv coverage.xml coverage-{envname}.xml
33
-