From 20e34bc19929d4518674cb2d043ed3d9eab2bea7 Mon Sep 17 00:00:00 2001 From: Arthur Vuillard Date: Thu, 11 May 2017 17:56:16 +0200 Subject: [PATCH] checkpoint for modoboa.admin tests in both python 2 and 3 --- modoboa/admin/models/alias.py | 2 +- modoboa/admin/tests/test_account.py | 8 ++--- modoboa/admin/tests/test_alias.py | 4 +-- modoboa/admin/tests/test_api.py | 34 +++++++++---------- modoboa/admin/tests/test_domain.py | 4 +-- modoboa/admin/tests/test_import_.py | 9 ++--- modoboa/admin/tests/test_user.py | 6 ++-- modoboa/admin/views/import_.py | 4 ++- .../commands/generate_postfix_maps.py | 5 +-- modoboa/core/password_hashers/base.py | 2 +- requirements.txt | 2 +- tox.ini | 3 +- 12 files changed, 41 insertions(+), 42 deletions(-) diff --git a/modoboa/admin/models/alias.py b/modoboa/admin/models/alias.py index 81274b538..5232468c8 100644 --- a/modoboa/admin/models/alias.py +++ b/modoboa/admin/models/alias.py @@ -63,7 +63,7 @@ class Alias(AdminObject): def generate_random_address(cls): """Generate a random address (local part).""" m = hashlib.md5() - for x in random.sample(xrange(10000000), 60): + for x in random.sample(range(10000000), 60): m.update(str(x)) return m.hexdigest()[:20] diff --git a/modoboa/admin/tests/test_account.py b/modoboa/admin/tests/test_account.py index 86ad607d5..b0927329b 100644 --- a/modoboa/admin/tests/test_account.py +++ b/modoboa/admin/tests/test_account.py @@ -243,12 +243,12 @@ class AccountTestCase(ModoTestCase): url = reverse("admin:account_detail", args=[account.pk]) response = self.client.get(url) self.assertEqual(response.status_code, 200) - self.assertIn("Summary", response.content) - self.assertIn("Administered domains", response.content) - self.assertNotIn("Resources usage", response.content) + self.assertIn("Summary", response.content.decode()) + self.assertIn("Administered domains", response.content.decode()) + self.assertNotIn("Resources usage", response.content.decode()) self.set_global_parameter("enable_admin_limits", True, app="limits") response = self.client.get(url) - self.assertIn("Resources usage", response.content) + self.assertIn("Resources usage", response.content.decode()) @skipIf(NO_LDAP, "No ldap module installed") diff --git a/modoboa/admin/tests/test_alias.py b/modoboa/admin/tests/test_alias.py index 62dc19bd2..b75310b24 100644 --- a/modoboa/admin/tests/test_alias.py +++ b/modoboa/admin/tests/test_alias.py @@ -265,8 +265,8 @@ class AliasTestCase(ModoTestCase): url = reverse("admin:alias_detail", args=[account.pk]) response = self.client.get(url) self.assertEqual(response.status_code, 200) - self.assertIn("Summary", response.content) - self.assertIn("Recipients", response.content) + self.assertIn("Summary", response.content.decode()) + self.assertIn("Recipients", response.content.decode()) def test_domainadmin_restrictions(self): """Check that restrictions are applied.""" diff --git a/modoboa/admin/tests/test_api.py b/modoboa/admin/tests/test_api.py index 2b35c54e4..44f146bcb 100644 --- a/modoboa/admin/tests/test_api.py +++ b/modoboa/admin/tests/test_api.py @@ -148,7 +148,7 @@ class DomainAliasAPITestCase(ModoAPITestCase): response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 201) - dalias = json.loads(response.content) + dalias = response.json() dalias = models.DomainAlias.objects.filter( pk=dalias["pk"]).first() self.assertEqual(dalias.target, target) @@ -217,17 +217,17 @@ class AccountAPITestCase(ModoAPITestCase): url = reverse("api:account-list") response = self.client.get(url) self.assertEqual(response.status_code, 200) - response = json.loads(response.content) + response = response.json() self.assertEqual(len(response), 5) response = self.client.get("{}?domain=test.com".format(url)) self.assertEqual(response.status_code, 200) - response = json.loads(response.content) + response = response.json() self.assertEqual(len(response), 2) response = self.client.get("{}?domain=pouet.com".format(url)) self.assertEqual(response.status_code, 200) - response = json.loads(response.content) + response = response.json() self.assertEqual(len(response), 0) def test_create_account(self): @@ -236,7 +236,7 @@ class AccountAPITestCase(ModoAPITestCase): response = self.client.post(url, self.ACCOUNT_DATA, format="json") self.assertEqual(response.status_code, 201) - account = json.loads(response.content) + account = response.json() user = core_models.User.objects.filter(pk=account["pk"]).first() self.assertIsNot(user, None) self.assertIsNot(user.mailbox, None) @@ -260,7 +260,7 @@ class AccountAPITestCase(ModoAPITestCase): self.assertEqual(response.status_code, 201) domain = admin_models.Domain.objects.get(name="test.com") admin = core_models.User.objects.get( - pk=json.loads(response.content)["pk"]) + pk=response.json()["pk"]) self.assertIn(admin, domain.admins) data["username"] = "domain_admin" @@ -275,7 +275,7 @@ class AccountAPITestCase(ModoAPITestCase): url = reverse("api:account-list") response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 201) - account = json.loads(response.content) + account = response.json() user = core_models.User.objects.filter(pk=account["pk"]).first() self.assertIsNot(user, None) self.assertIsNot(user.mailbox, None) @@ -302,7 +302,7 @@ class AccountAPITestCase(ModoAPITestCase): url = reverse("api:account-list") response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 400) - errors = json.loads(response.content) + errors = response.json() self.assertIn("password", errors) def test_create_account_as_domadmin(self): @@ -320,7 +320,7 @@ class AccountAPITestCase(ModoAPITestCase): url = reverse("api:account-list") response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 400) - errors = json.loads(response.content) + errors = response.json() self.assertIn("domain", errors) def test_create_account_bad_master_user(self): @@ -330,7 +330,7 @@ class AccountAPITestCase(ModoAPITestCase): url = reverse("api:account-list") response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 400) - errors = json.loads(response.content) + errors = response.json() self.assertIn("master_user", errors) def test_update_account(self): @@ -432,12 +432,12 @@ class AccountAPITestCase(ModoAPITestCase): response = self.client.get( "{}?email={}".format(url, "user@test.com")) self.assertEqual(response.status_code, 200) - content = json.loads(response.content) + content = response.json() self.assertTrue(content["exists"]) response = self.client.get( "{}?email={}".format(url, "pipo@test.com")) self.assertEqual(response.status_code, 200) - content = json.loads(response.content) + content = response.json() self.assertFalse(content["exists"]) response = self.client.get(url) self.assertEqual(response.status_code, 400) @@ -487,12 +487,12 @@ class AliasAPITestCase(ModoAPITestCase): url = reverse("api:alias-list") response = self.client.get(url) self.assertEqual(response.status_code, 200) - response = json.loads(response.content) + response = response.json() self.assertEqual(len(response), 3) response = self.client.get("{}?domain=test.com".format(url)) self.assertEqual(response.status_code, 200) - response = json.loads(response.content) + response = response.json() self.assertEqual(len(response), 3) def test_get_alias(self): @@ -501,7 +501,7 @@ class AliasAPITestCase(ModoAPITestCase): url = reverse("api:alias-detail", args=[al.pk]) response = self.client.get(url) self.assertEqual(response.status_code, 200) - response = json.loads(response.content) + response = response.json() self.assertEqual(response["recipients"], ["user@test.com"]) def test_create_alias(self): @@ -510,7 +510,7 @@ class AliasAPITestCase(ModoAPITestCase): response = self.client.post(url, self.ALIAS_DATA, format="json") self.assertEqual(response.status_code, 201) - alias = json.loads(response.content) + alias = json.loads(response.content.decode('utf-8')) alias = models.Alias.objects.filter(pk=alias["pk"]).first() domadmin = core_models.User.objects.get(username="admin@test.com") self.assertTrue(domadmin.can_access(alias)) @@ -541,7 +541,7 @@ class AliasAPITestCase(ModoAPITestCase): data["address"] = "alias_fromapi@test2.com" response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 400) - errors = json.loads(response.content) + errors = response.json() self.assertIn("address", errors) def test_update_alias(self): diff --git a/modoboa/admin/tests/test_domain.py b/modoboa/admin/tests/test_domain.py index 0a7d64f57..597860fc0 100644 --- a/modoboa/admin/tests/test_domain.py +++ b/modoboa/admin/tests/test_domain.py @@ -4,8 +4,6 @@ from __future__ import unicode_literals """Domain related test cases.""" -import json - from django.core.urlresolvers import reverse from modoboa.core.models import User @@ -213,7 +211,7 @@ class DomainTestCase(ModoTestCase): """Test the 'domain_flat_list' view.""" response = self.client.get(reverse("admin:domain_flat_list")) self.assertEqual(response.status_code, 200) - content = json.loads(response.content) + content = response.json() self.assertIn("test.com", content) self.assertIn("test2.com", content) diff --git a/modoboa/admin/tests/test_import_.py b/modoboa/admin/tests/test_import_.py index c495ea61a..ac3252245 100644 --- a/modoboa/admin/tests/test_import_.py +++ b/modoboa/admin/tests/test_import_.py @@ -4,6 +4,7 @@ from __future__ import unicode_literals from django.core.files.base import ContentFile from django.core.urlresolvers import reverse +from django.utils.encoding import force_bytes from modoboa.core.models import User from modoboa.lib.tests import ModoTestCase @@ -26,7 +27,7 @@ class ImportTestCase(ModoTestCase): def test_domains_import(self): response = self.client.get(reverse("admin:domain_import")) self.assertEqual(response.status_code, 200) - self.assertIn("Provide a CSV", response.content) + self.assertIn("Provide a CSV", response.content.decode()) f = ContentFile(b"""domain; domain1.com; 1000; 100; True domain; domain2.com; 1000; 200; False @@ -88,7 +89,7 @@ domainalias;test.alias;test.com;True def test_identities_import(self): response = self.client.get(reverse("admin:identity_import")) self.assertEqual(response.status_code, 200) - self.assertIn("Provide a CSV", response.content) + self.assertIn("Provide a CSV", response.content.decode()) f = ContentFile(b""" account; user1@test.com; toto; User; One; True; SimpleUsers; user1@test.com; 0 @@ -179,7 +180,7 @@ account; user1@test.com; toto; User; One; True; SimpleUsers; user1@test.com; ; t reverse("admin:identity_import"), {"sourcefile": f, "crypt_password": True} ) - self.assertIn('wrong quota value', resp.content) + self.assertIn('wrong quota value', resp.content.decode()) def test_import_domain_by_domainadmin(self): """Check if a domain admin is not allowed to import a domain.""" @@ -213,7 +214,7 @@ account; user1@test.com; toto; User; One; True; SimpleUsers; user1@test.com; 40 reverse("admin:identity_import"), {"sourcefile": f, "crypt_password": True} ) - self.assertIn("Domain quota exceeded", resp.content) + self.assertIn("Domain quota exceeded", resp.content.decode()) def test_import_missing_quota(self): f = ContentFile(b""" diff --git a/modoboa/admin/tests/test_user.py b/modoboa/admin/tests/test_user.py index 65a6efc06..2eccfc900 100644 --- a/modoboa/admin/tests/test_user.py +++ b/modoboa/admin/tests/test_user.py @@ -2,8 +2,6 @@ from __future__ import unicode_literals -import json - from django.core.urlresolvers import reverse from modoboa.core.models import User @@ -30,7 +28,7 @@ class ForwardTestCase(ModoTestCase): ) response = self.client.get(url) self.assertEqual(response.status_code, 200) - content = json.loads(response.content) + content = response.json() self.assertIn("user@extdomain.com", content["content"]) self.assertNotIn("user@test.com", content["content"]) forward = Alias.objects.get(address="user@test.com", internal=False) @@ -43,5 +41,5 @@ class ForwardTestCase(ModoTestCase): self.ajax_post(url, {"dest": "", "keepcopies": False}) response = self.client.get(url) self.assertEqual(response.status_code, 200) - content = json.loads(response.content) + content = response.json() self.assertNotIn("user@extdomain.com", content["content"]) diff --git a/modoboa/admin/views/import_.py b/modoboa/admin/views/import_.py index 951ae5940..a157e71f9 100644 --- a/modoboa/admin/views/import_.py +++ b/modoboa/admin/views/import_.py @@ -4,6 +4,8 @@ from __future__ import unicode_literals import csv +from io import StringIO + from django.contrib.auth.decorators import ( login_required, permission_required, user_passes_test ) @@ -11,7 +13,7 @@ from django.core.urlresolvers import reverse from django.db import transaction from django.shortcuts import render from django.utils.translation import ugettext as _ -from django.utils.encoding import smart_str +from django.utils.encoding import smart_str, force_text from reversion import revisions as reversion diff --git a/modoboa/core/management/commands/generate_postfix_maps.py b/modoboa/core/management/commands/generate_postfix_maps.py index 5fc15510f..2e0f7fc05 100644 --- a/modoboa/core/management/commands/generate_postfix_maps.py +++ b/modoboa/core/management/commands/generate_postfix_maps.py @@ -10,6 +10,7 @@ from django.conf import settings from django.core.management.base import BaseCommand from django.template import Context, Template from django.utils import timezone +from django.utils.encoding import force_bytes import dj_database_url @@ -68,7 +69,7 @@ class Command(BaseCommand): fname not in self.__checksums) if condition: return True - with open(path) as fp: + with open(path, mode="rb") as fp: checksum = hashlib.md5(fp.read()).hexdigest() return checksum == self.__checksums[fname]["checksum"] @@ -142,7 +143,7 @@ query = {{ query|safe }} fullpath = os.path.join(destdir, mapobject.filename) with open(fullpath, "w") as fp: fp.write(content) - return hashlib.md5(content).hexdigest() + return hashlib.md5(force_bytes(content)).hexdigest() def handle(self, *args, **options): """Command entry point.""" diff --git a/modoboa/core/password_hashers/base.py b/modoboa/core/password_hashers/base.py index 3f4b0c8d6..73c4b237a 100644 --- a/modoboa/core/password_hashers/base.py +++ b/modoboa/core/password_hashers/base.py @@ -92,7 +92,7 @@ class CRYPTHasher(PasswordHasher): def _encrypt(self, clearvalue, salt=None): if salt is None: - salt = "".join(Random().sample(string.letters + string.digits, 2)) + salt = "".join(Random().sample(string.ascii_letters + string.digits, 2)) return crypt.crypt(clearvalue, salt) diff --git a/requirements.txt b/requirements.txt index 48c0f433b..08dcfb547 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,7 +15,7 @@ djangorestframework==3.6.2 argparse # bcrypt requires libffi-dev bcrypt==2.0.0 -dnspython==1.12.0 +dnspython==1.15.0 feedparser==5.2.1 gevent==1.2.1 ipaddress diff --git a/tox.ini b/tox.ini index 6d4ef5c08..70d428bdb 100644 --- a/tox.ini +++ b/tox.ini @@ -4,8 +4,7 @@ envlist = py27,py34 [testenv] changedir=test_project commands = - python ../tests.py - coverage run --source modoboa manage.py test modoboa.core modoboa.lib modoboa.admin modoboa.limits modoboa.relaydomains + coverage run --source modoboa manage.py test modoboa.admin coverage report --show-missing deps = -r{toxinidir}/test-requirements.txt