diff --git a/.travis.yml b/.travis.yml
index 19ed0fbedf5d..f522f58574bf 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -24,10 +24,10 @@ jobs:
- { stage: python3working, python: 3.6, env: TOXENV=assets }
- { stage: python3working, python: 3.6, env: TOXENV=es }
- { stage: python3working, python: 3.6, env: TOXENV=addons-versions-and-files }
+ - { stage: python3working, python: 3.6, env: TOXENV=devhub }
- { stage: python3working, python: 3.6, env: TOXENV=reviewers-and-zadmin }
- { stage: python3working, python: 3.6, env: TOXENV=accounts-users-and-ratings }
- { stage: python3working, python: 3.6, env: TOXENV=main }
- - { stage: python3, python: 3.6, env: TOXENV=devhub }
- { stage: python3, python: 3.6, env: TOXENV=amo-lib-locales-and-signing }
env:
diff --git a/src/olympia/addons/forms.py b/src/olympia/addons/forms.py
index 762a1b2a7279..da4fa93e4138 100644
--- a/src/olympia/addons/forms.py
+++ b/src/olympia/addons/forms.py
@@ -5,6 +5,7 @@
from django.conf import settings
from django.core.files.storage import default_storage as storage
from django.forms.formsets import BaseFormSet, formset_factory
+from django.utils.encoding import force_text
from django.utils.translation import ugettext, ugettext_lazy as _, ungettext
import six
@@ -229,7 +230,7 @@ def clean_categories(self):
'You can have only {0} categories.',
max_cat).format(max_cat))
- has_misc = filter(lambda x: x.misc, categories)
+ has_misc = list(filter(lambda x: x.misc, categories))
if has_misc and total > 1:
raise forms.ValidationError(ugettext(
'The miscellaneous category cannot be combined with '
@@ -292,7 +293,7 @@ def icons():
dirs, files = storage.listdir(settings.ADDON_ICONS_DEFAULT_PATH)
for fname in files:
if b'32' in fname and b'default' not in fname:
- icon_name = fname.split(b'-')[0]
+ icon_name = force_text(fname.split(b'-')[0])
icons.append(('icon/%s' % icon_name, icon_name))
return sorted(icons)
diff --git a/src/olympia/devhub/file_validation_annotations.py b/src/olympia/devhub/file_validation_annotations.py
index da97165ac0cc..c378f57fda4e 100644
--- a/src/olympia/devhub/file_validation_annotations.py
+++ b/src/olympia/devhub/file_validation_annotations.py
@@ -5,7 +5,6 @@
from xml.parsers.expat import ExpatError
from django.utils.translation import ugettext
-from django.utils.encoding import force_bytes
from olympia import amo
from olympia.lib.akismet.models import AkismetReport
@@ -123,10 +122,8 @@ def annotate_search_plugin_validation(results, file_path, channel):
return
try:
- # Requires bytes because defusedxml fails to detect
- # unicode strings as filenames.
- # https://gist.github.com/EnTeQuAk/25f99701d8b123f7611acd6ce0d5840b
- dom = minidom.parse(force_bytes(file_path))
+ with open(file_path, 'r') as file_obj:
+ dom = minidom.parse(file_obj)
except DefusedXmlException:
url = 'https://pypi.python.org/pypi/defusedxml/0.3#attack-vectors'
insert_validation_message(
diff --git a/src/olympia/devhub/forms.py b/src/olympia/devhub/forms.py
index ad2d01142233..3f2b8793eba5 100644
--- a/src/olympia/devhub/forms.py
+++ b/src/olympia/devhub/forms.py
@@ -67,15 +67,15 @@ def clean(self):
if any(self.errors):
return
# cleaned_data could be None if it's the empty extra form.
- data = filter(None, [f.cleaned_data for f in self.forms
- if not f.cleaned_data.get('DELETE', False)])
+ data = list(filter(None, [f.cleaned_data for f in self.forms
+ if not f.cleaned_data.get('DELETE', False)]))
if not any(d['role'] == amo.AUTHOR_ROLE_OWNER for d in data):
raise forms.ValidationError(
ugettext('Must have at least one owner.'))
if not any(d['listed'] for d in data):
raise forms.ValidationError(
ugettext('At least one author must be listed.'))
- users = [d['user'] for d in data]
+ users = [d['user'].id for d in data]
if sorted(users) != sorted(set(users)):
raise forms.ValidationError(
ugettext('An author can only be listed once.'))
@@ -313,7 +313,7 @@ def clean_source(self):
'Unsupported file type, please upload an archive '
'file {extensions}.'.format(
extensions=valid_extensions_string)))
- except (zipfile.BadZipfile, tarfile.ReadError, IOError):
+ except (zipfile.BadZipfile, tarfile.ReadError, IOError, EOFError):
raise forms.ValidationError(
ugettext('Invalid or broken archive.'))
return source
@@ -420,9 +420,9 @@ def __init__(self, *args, **kwargs):
self.fields['max'].queryset = qs.all()
def clean(self):
- min = self.cleaned_data.get('min')
- max = self.cleaned_data.get('max')
- if not (min and max and min.version_int <= max.version_int):
+ min_ = self.cleaned_data.get('min')
+ max_ = self.cleaned_data.get('max')
+ if not (min_ and max_ and min_.version_int <= max_.version_int):
raise forms.ValidationError(ugettext('Invalid version range.'))
return self.cleaned_data
@@ -465,8 +465,8 @@ def clean(self):
if any(self.errors):
return
- apps = filter(None, [f.cleaned_data for f in self.forms
- if not f.cleaned_data.get('DELETE', False)])
+ apps = list(filter(None, [f.cleaned_data for f in self.forms
+ if not f.cleaned_data.get('DELETE', False)]))
if not apps:
# At this point, we're raising a global error and re-displaying the
@@ -653,7 +653,7 @@ def clean(self):
super(CombinedNameSummaryCleanMixin, self).clean()
name_summary_locales = set(
list(self.cleaned_data.get('name', {}).keys()) +
- self.cleaned_data.get('summary', {}).keys())
+ list(self.cleaned_data.get('summary', {}).keys()))
default_locale = self.instance.default_locale.lower()
name_values = self.cleaned_data.get('name') or {}
name_default = name_values.get(default_locale) or ''
diff --git a/src/olympia/devhub/tasks.py b/src/olympia/devhub/tasks.py
index 0395565b017f..2f98c7e3e3b4 100644
--- a/src/olympia/devhub/tasks.py
+++ b/src/olympia/devhub/tasks.py
@@ -17,6 +17,7 @@
from django.core.validators import ValidationError
from django.db import transaction
from django.template import loader
+from django.utils.encoding import force_text
from django.utils.translation import ugettext
import celery
@@ -161,7 +162,7 @@ def wrapper(task, akismet_results, id_or_path, **kwargs):
task.ignore_result = True
try:
data = fn(id_or_path, **kwargs)
- results = json.loads(data)
+ results = json.loads(force_text(data))
if akismet_results:
annotations.annotate_akismet_spam_check(
results, akismet_results)
@@ -448,7 +449,7 @@ def run_addons_linter(path, channel):
if error:
raise ValueError(error)
- parsed_data = json.loads(output)
+ parsed_data = json.loads(force_text(output))
result = json.dumps(fix_addons_linter_output(parsed_data, channel))
track_validation_stats(result)
@@ -460,7 +461,7 @@ def track_validation_stats(json_result):
"""
Given a raw JSON string of validator results, log some stats.
"""
- result = json.loads(json_result)
+ result = json.loads(force_text(json_result))
result_kind = 'success' if result['errors'] == 0 else 'failure'
statsd.incr('devhub.linter.results.all.{}'.format(result_kind))
diff --git a/src/olympia/devhub/templatetags/jinja_helpers.py b/src/olympia/devhub/templatetags/jinja_helpers.py
index afc63979f49f..950bb12208ce 100644
--- a/src/olympia/devhub/templatetags/jinja_helpers.py
+++ b/src/olympia/devhub/templatetags/jinja_helpers.py
@@ -1,5 +1,3 @@
-import urllib
-
from collections import defaultdict
from django.utils.encoding import force_bytes
@@ -9,6 +7,7 @@
import six
from django_jinja import library
+from six.moves.urllib.parse import unquote_to_bytes
from olympia import amo
from olympia.access import acl
@@ -120,7 +119,7 @@ def display_url(url):
Note: returns a Unicode object, not a valid URL.
"""
url = force_bytes(url, errors='replace')
- return urllib.unquote(url).decode('utf-8', errors='replace')
+ return unquote_to_bytes(url).decode('utf-8', errors='replace')
@library.global_function
diff --git a/src/olympia/devhub/tests/test_feeds.py b/src/olympia/devhub/tests/test_feeds.py
index 3999ef6001f5..06ce05005ce0 100644
--- a/src/olympia/devhub/tests/test_feeds.py
+++ b/src/olympia/devhub/tests/test_feeds.py
@@ -1,5 +1,7 @@
import uuid
+from django.utils.encoding import force_text
+
import six
from six.moves.urllib_parse import urlencode
@@ -176,34 +178,35 @@ def test_filter_addon_otherguy(self):
def test_rss(self):
self.log_creates(5)
# This will give us a new RssKey
- r = self.get_response()
+ self.get_response()
key = RssKey.objects.get()
assert isinstance(key.key, uuid.UUID)
- r = self.get_response(privaterss=key.key)
- assert r['content-type'] == 'application/rss+xml; charset=utf-8'
- assert '
Recent Changes for My Add-ons' in r.content
+ res = self.get_response(privaterss=key.key)
+ assert res['content-type'] == 'application/rss+xml; charset=utf-8'
+ assert b'Recent Changes for My Add-ons' in res.content
def test_rss_accepts_verbose(self):
self.log_creates(5)
- r = self.get_response()
+ self.get_response()
key = RssKey.objects.get()
- r = self.get_response(privaterss=str(key.key))
- assert r['content-type'] == 'application/rss+xml; charset=utf-8'
- assert 'Recent Changes for My Add-ons' in r.content
+ res = self.get_response(privaterss=str(key.key))
+ assert res['content-type'] == 'application/rss+xml; charset=utf-8'
+ assert b'Recent Changes for My Add-ons' in res.content
def test_rss_single(self):
self.log_creates(5)
self.log_creates(13, self.addon2)
# This will give us a new RssKey
- r = self.get_response(addon=self.addon.id)
+ self.get_response(addon=self.addon.id)
key = RssKey.objects.get()
- r = self.get_response(privaterss=key.key)
- assert r['content-type'] == 'application/rss+xml; charset=utf-8'
- assert len(pq(r.content)('item')) == 5
- assert 'Recent Changes for %s' % self.addon in r.content
+ res = self.get_response(privaterss=key.key)
+ assert res['content-type'] == 'application/rss+xml; charset=utf-8'
+ assert len(pq(res.content)('item')) == 5
+ assert 'Recent Changes for %s' % self.addon in (
+ force_text(res.content))
def test_rss_unlisted_addon(self):
"""Unlisted addon logs appear in the rss feed."""
@@ -293,11 +296,11 @@ def test_hidden(self):
res = self.get_response(addon=self.addon.id)
key = RssKey.objects.get()
res = self.get_response(privaterss=key.key)
- assert "Comment on" not in res.content
+ assert b'Comment on' not in res.content
def test_no_guid(self):
self.log_creates(1)
self.get_response(addon=self.addon.id)
key = RssKey.objects.get()
res = self.get_response(privaterss=key.key)
- assert "" not in res.content
+ assert b'' not in res.content
diff --git a/src/olympia/devhub/tests/test_forms.py b/src/olympia/devhub/tests/test_forms.py
index c2a08c4f14e9..c85790390335 100644
--- a/src/olympia/devhub/tests/test_forms.py
+++ b/src/olympia/devhub/tests/test_forms.py
@@ -6,6 +6,7 @@
from django.conf import settings
from django.core.files.storage import default_storage as storage
from django.utils import translation
+from django.utils.encoding import force_text
import mock
import pytest
@@ -255,8 +256,8 @@ def test_preview_modified(self, update_mock):
name = 'transparent.png'
form = forms.PreviewForm({'caption': 'test', 'upload_hash': name,
'position': 1})
- with storage.open(os.path.join(self.dest, name), 'w') as f:
- shutil.copyfileobj(open(get_image_path(name)), f)
+ with storage.open(os.path.join(self.dest, name), 'wb') as f:
+ shutil.copyfileobj(open(get_image_path(name), 'rb'), f)
assert form.is_valid()
form.save(addon)
assert update_mock.called
@@ -267,8 +268,8 @@ def test_preview_size(self, pngcrush_image_mock):
name = 'teamaddons.jpg'
form = forms.PreviewForm({'caption': 'test', 'upload_hash': name,
'position': 1})
- with storage.open(os.path.join(self.dest, name), 'w') as f:
- shutil.copyfileobj(open(get_image_path(name)), f)
+ with storage.open(os.path.join(self.dest, name), 'wb') as f:
+ shutil.copyfileobj(open(get_image_path(name), 'rb'), f)
assert form.is_valid()
form.save(addon)
preview = addon.previews.all()[0]
@@ -433,7 +434,8 @@ def test_success(self, save_persona_image_mock,
# Upload header image.
img = open(get_image_path('persona-header.jpg'), 'rb')
r_ajax = self.client.post(header_url, {'upload_image': img})
- data.update(header_hash=json.loads(r_ajax.content)['upload_hash'])
+ content = json.loads(force_text(r_ajax.content))
+ data.update(header_hash=content['upload_hash'])
# Populate and save form.
self.post()
diff --git a/src/olympia/devhub/tests/test_helpers.py b/src/olympia/devhub/tests/test_helpers.py
index e0e57cd1c96d..e76699d796fd 100644
--- a/src/olympia/devhub/tests/test_helpers.py
+++ b/src/olympia/devhub/tests/test_helpers.py
@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
-import urllib
-
from django.utils import translation
+from django.utils.encoding import force_bytes, force_text
import pytest
import six
from mock import Mock
+from six.moves.urllib.parse import quote
from olympia import amo
from olympia.activity.models import ActivityLog
@@ -72,17 +72,17 @@ class TestDisplayUrl(amo.tests.BaseTestCase):
def setUp(self):
super(TestDisplayUrl, self).setUp()
- self.raw_url = u'http://host/%s' % 'フォクすけといっしょ'.decode('utf8')
+ self.raw_url = u'http://host/%s' % u'フォクすけといっしょ'
def test_utf8(self):
- url = urllib.quote(self.raw_url.encode('utf8'))
- assert render('{{ url|display_url }}', {'url': url}) == (
+ url = quote(self.raw_url.encode('utf8'))
+ assert render(u'{{ url|display_url }}', {'url': url}) == (
self.raw_url)
def test_unicode(self):
- url = urllib.quote(self.raw_url.encode('utf8'))
- url = six.text_type(url, 'utf8')
- assert render('{{ url|display_url }}', {'url': url}) == (
+ url = quote(self.raw_url.encode('utf8'))
+ url = force_text(force_bytes(url, 'utf8'), 'utf8')
+ assert render(u'{{ url|display_url }}', {'url': url}) == (
self.raw_url)
diff --git a/src/olympia/devhub/tests/test_tasks.py b/src/olympia/devhub/tests/test_tasks.py
index 97dc5a5a314a..f670671d4583 100644
--- a/src/olympia/devhub/tests/test_tasks.py
+++ b/src/olympia/devhub/tests/test_tasks.py
@@ -75,7 +75,7 @@ def _uploader(resize_size, final_size):
original_size = (339, 128)
src = tempfile.NamedTemporaryFile(
- mode='r+w+b', suffix='.png', delete=False, dir=settings.TMP_PATH)
+ mode='r+b', suffix='.png', delete=False, dir=settings.TMP_PATH)
if not isinstance(final_size, list):
final_size = [final_size]
@@ -122,18 +122,20 @@ def test_recreate_previews(pngcrush_image_mock):
addon = addon_factory()
# Set up the preview so it has files in the right places.
preview_no_original = Preview.objects.create(addon=addon)
- with storage.open(preview_no_original.image_path, 'w') as dest:
- shutil.copyfileobj(open(get_image_path('preview_landscape.jpg')), dest)
- with storage.open(preview_no_original.thumbnail_path, 'w') as dest:
- shutil.copyfileobj(open(get_image_path('mozilla.png')), dest)
+ with storage.open(preview_no_original.image_path, 'wb') as dest:
+ shutil.copyfileobj(open(get_image_path('preview_landscape.jpg'), 'rb'),
+ dest)
+ with storage.open(preview_no_original.thumbnail_path, 'wb') as dest:
+ shutil.copyfileobj(open(get_image_path('mozilla.png'), 'rb'), dest)
# And again but this time with an "original" image.
preview_has_original = Preview.objects.create(addon=addon)
- with storage.open(preview_has_original.image_path, 'w') as dest:
- shutil.copyfileobj(open(get_image_path('preview_landscape.jpg')), dest)
- with storage.open(preview_has_original.thumbnail_path, 'w') as dest:
- shutil.copyfileobj(open(get_image_path('mozilla.png')), dest)
- with storage.open(preview_has_original.original_path, 'w') as dest:
- shutil.copyfileobj(open(get_image_path('teamaddons.jpg')), dest)
+ with storage.open(preview_has_original.image_path, 'wb') as dest:
+ shutil.copyfileobj(open(get_image_path('preview_landscape.jpg'), 'rb'),
+ dest)
+ with storage.open(preview_has_original.thumbnail_path, 'wb') as dest:
+ shutil.copyfileobj(open(get_image_path('mozilla.png'), 'rb'), dest)
+ with storage.open(preview_has_original.original_path, 'wb') as dest:
+ shutil.copyfileobj(open(get_image_path('teamaddons.jpg'), 'rb'), dest)
tasks.recreate_previews([addon.id])
diff --git a/src/olympia/devhub/tests/test_views.py b/src/olympia/devhub/tests/test_views.py
index 6188b95a23b8..2b64da57d60c 100644
--- a/src/olympia/devhub/tests/test_views.py
+++ b/src/olympia/devhub/tests/test_views.py
@@ -9,6 +9,7 @@
from django.core.files.storage import default_storage as storage
from django.test import RequestFactory
from django.test.utils import override_settings
+from django.utils.encoding import force_text
from django.utils.translation import trim_whitespace
import mock
@@ -425,7 +426,7 @@ def test_counts(self):
version=addon.current_version)
url = reverse('devhub.versions.stats', args=[addon.slug])
- data = json.loads(self.client.get(url).content)
+ data = json.loads(force_text(self.client.get(url).content))
exp = {str(version.id):
{'reviews': 10, 'files': 1, 'version': version.version,
'id': version.id}}
@@ -531,7 +532,7 @@ def test_basic_logged_out(self):
response = self.client.get(self.url)
assert response.status_code == 200
self.assertTemplateUsed(response, 'devhub/index.html')
- assert 'Customize Firefox' in response.content
+ assert b'Customize Firefox' in response.content
def test_default_lang_selected(self):
self.client.logout()
@@ -543,7 +544,7 @@ def test_basic_logged_in(self):
response = self.client.get(self.url)
assert response.status_code == 200
self.assertTemplateUsed(response, 'devhub/index.html')
- assert 'My Add-ons' in response.content
+ assert b'My Add-ons' in response.content
def test_my_addons_addon_versions_link(self):
assert self.client.login(email='del@icio.us')
@@ -953,7 +954,7 @@ def test_detail_json(self):
response = self.client.get(reverse('devhub.upload_detail',
args=[upload.uuid.hex, 'json']))
assert response.status_code == 200
- data = json.loads(response.content)
+ data = json.loads(force_text(response.content))
assert data['validation']['errors'] == 1
assert data['url'] == (
@@ -1042,7 +1043,7 @@ def test_no_servererror_on_missing_version(self):
upload = FileUpload.objects.get()
response = self.client.get(
reverse('devhub.upload_detail', args=[upload.uuid.hex, 'json']))
- data = json.loads(response.content)
+ data = json.loads(force_text(response.content))
message = [(m['message'], m.get('type') == 'error')
for m in data['validation']['messages']]
expected = [(u'"/version" is a required property', True)]
@@ -1057,7 +1058,7 @@ def test_unparsable_xpi(self, flag_is_active, v):
upload = FileUpload.objects.get()
response = self.client.get(
reverse('devhub.upload_detail', args=[upload.uuid.hex, 'json']))
- data = json.loads(response.content)
+ data = json.loads(force_text(response.content))
message = [(m['message'], m.get('fatal', False))
for m in data['validation']['messages']]
assert message == [
@@ -1074,7 +1075,7 @@ def test_experiment_xpi_allowed(self, mock_validator):
upload = FileUpload.objects.get()
response = self.client.get(reverse('devhub.upload_detail',
args=[upload.uuid.hex, 'json']))
- data = json.loads(response.content)
+ data = json.loads(force_text(response.content))
assert data['validation']['messages'] == []
@mock.patch('olympia.devhub.tasks.run_addons_linter')
@@ -1085,7 +1086,7 @@ def test_experiment_xpi_not_allowed(self, mock_validator):
upload = FileUpload.objects.get()
response = self.client.get(reverse('devhub.upload_detail',
args=[upload.uuid.hex, 'json']))
- data = json.loads(response.content)
+ data = json.loads(force_text(response.content))
assert data['validation']['messages'] == [
{u'tier': 1, u'message': u'You cannot submit this type of add-on',
u'fatal': True, u'type': u'error'}]
@@ -1100,7 +1101,7 @@ def test_system_addon_allowed(self, mock_validator):
upload = FileUpload.objects.get()
response = self.client.get(reverse('devhub.upload_detail',
args=[upload.uuid.hex, 'json']))
- data = json.loads(response.content)
+ data = json.loads(force_text(response.content))
assert data['validation']['messages'] == []
@mock.patch('olympia.devhub.tasks.run_addons_linter')
@@ -1113,7 +1114,7 @@ def test_system_addon_not_allowed_not_mozilla(self, mock_validator):
upload = FileUpload.objects.get()
response = self.client.get(reverse('devhub.upload_detail',
args=[upload.uuid.hex, 'json']))
- data = json.loads(response.content)
+ data = json.loads(force_text(response.content))
assert data['validation']['messages'] == [
{u'tier': 1,
u'message': u'You cannot submit an add-on with a guid ending '
@@ -1133,7 +1134,7 @@ def test_mozilla_signed_allowed(self, mock_get_signature, mock_validator):
upload = FileUpload.objects.get()
response = self.client.get(reverse('devhub.upload_detail',
args=[upload.uuid.hex, 'json']))
- data = json.loads(response.content)
+ data = json.loads(force_text(response.content))
assert data['validation']['messages'] == []
@mock.patch('olympia.files.utils.get_signer_organizational_unit_name')
@@ -1146,7 +1147,7 @@ def test_mozilla_signed_not_allowed_not_mozilla(self, mock_get_signature):
upload = FileUpload.objects.get()
response = self.client.get(reverse('devhub.upload_detail',
args=[upload.uuid.hex, 'json']))
- data = json.loads(response.content)
+ data = json.loads(force_text(response.content))
assert data['validation']['messages'] == [
{u'tier': 1,
u'message': u'You cannot submit a Mozilla Signed Extension',
@@ -1172,7 +1173,7 @@ def test_legacy_mozilla_signed_fx57_compat_allowed(self):
upload = FileUpload.objects.get()
response = self.client.get(reverse('devhub.upload_detail',
args=[upload.uuid.hex, 'json']))
- data = json.loads(response.content)
+ data = json.loads(force_text(response.content))
msg = data['validation']['messages'][0]
@@ -1195,7 +1196,7 @@ def test_system_addon_update_allowed(self, mock_validator):
upload = FileUpload.objects.get()
response = self.client.get(reverse('devhub.upload_detail_for_version',
args=[addon.slug, upload.uuid.hex]))
- data = json.loads(response.content)
+ data = json.loads(force_text(response.content))
assert data['validation']['messages'] == []
def test_legacy_langpacks_disallowed(self):
@@ -1204,7 +1205,7 @@ def test_legacy_langpacks_disallowed(self):
upload = FileUpload.objects.get()
response = self.client.get(reverse('devhub.upload_detail',
args=[upload.uuid.hex, 'json']))
- data = json.loads(response.content)
+ data = json.loads(force_text(response.content))
assert data['validation']['messages'][0]['id'] == [
u'validation', u'messages', u'legacy_addons_unsupported'
]
@@ -1246,7 +1247,7 @@ def test_akismet_reports_created_ham_outcome(self, comment_check_mock):
report = AkismetReport.objects.get(upload_instance=upload)
assert report.comment_type == 'product-name'
assert report.comment == 'Beastify' # the addon's name
- assert 'spam' not in response.content
+ assert b'spam' not in response.content
@override_switch('akismet-spam-check', active=True)
@override_switch('akismet-addon-action', active=False)
@@ -1266,7 +1267,7 @@ def test_akismet_reports_created_spam_outcome_logging_only(self):
assert report.comment_type == 'product-name'
assert report.comment == 'Beastify' # the addon's name
assert report.result == AkismetReport.MAYBE_SPAM
- assert 'spam' not in response.content
+ assert b'spam' not in response.content
@override_switch('akismet-spam-check', active=True)
@override_switch('akismet-addon-action', active=True)
@@ -1285,9 +1286,9 @@ def test_akismet_reports_created_spam_outcome_action_taken(self):
report = AkismetReport.objects.get(upload_instance=upload)
assert report.comment_type == 'product-name'
assert report.comment == 'Beastify' # the addon's name
- assert 'spam' in response.content
+ assert b'spam' in response.content
assert report.result == AkismetReport.MAYBE_SPAM
- data = json.loads(response.content)
+ data = json.loads(force_text(response.content))
assert data['validation']['messages'][0]['id'] == [
u'validation', u'messages', u'akismet_is_spam_name'
]
@@ -1317,7 +1318,7 @@ def test_akismet_reports_created_l10n(self, comment_check_mock):
u'Varsling ved trykk på lenke i18n', # nb_NO
]
assert report.comment in names
- assert 'spam' not in response.content
+ assert b'spam' not in response.content
@override_switch('akismet-spam-check', active=True)
def test_akismet_reports_not_created_for_unlisted(self):
@@ -1446,8 +1447,8 @@ def test_unique_version_num(self):
version='