Added unit tests.

This commit is contained in:
Antoine Nguyen
2021-06-03 21:56:45 +02:00
parent d3e66dc6cc
commit 575316f9af
5 changed files with 280 additions and 15 deletions
+9 -14
View File
@@ -283,13 +283,7 @@ class WritableAccountSerializer(v1_serializers.WritableAccountSerializer):
data["mailbox"] = {
"use_domain_quota": True
}
condition = (
not data.get("random_password") and (
data.get("password") or
not self.partial
)
)
if condition:
if data.get("password") or not self.partial:
password = data.get("password")
if password:
try:
@@ -302,6 +296,11 @@ class WritableAccountSerializer(v1_serializers.WritableAccountSerializer):
raise serializers.ValidationError({
"password": _("This field is required.")
})
aliases = data.get("aliases")
if aliases and "mailbox" not in data:
raise serializers.ValidationError({
"aliases": _("A mailbox is required to create aliases.")
})
domain_names = data.get("domains")
if not domain_names:
return data
@@ -323,13 +322,9 @@ class WritableAccountSerializer(v1_serializers.WritableAccountSerializer):
mailbox_data = validated_data.pop("mailbox", None)
role = validated_data.pop("role")
domains = validated_data.pop("domains", [])
random_password = validated_data.pop("random_password", False)
aliases = validated_data.pop("aliases", None)
user = core_models.User(**validated_data)
if random_password:
password = lib.make_password()
else:
password = validated_data.pop("password")
password = validated_data.pop("password")
user.set_password(password)
if "language" not in validated_data:
user.language = settings.LANGUAGE_CODE
@@ -343,8 +338,8 @@ class WritableAccountSerializer(v1_serializers.WritableAccountSerializer):
for alias in aliases:
models.Alias.objects.create(
creator=creator,
domain=alias.domain,
address=alias.localpart,
domain=alias["domain"],
address="{}@{}".format(alias["localpart"], alias["domain"]),
recipients=[user.username]
)
return user
+203
View File
@@ -0,0 +1,203 @@
"""API v2 tests."""
from django.urls import reverse
from rest_framework.authtoken.models import Token
from modoboa.admin import factories, models
from modoboa.core import models as core_models
from modoboa.lib.tests import ModoAPITestCase
class DomainViewSetTestCase(ModoAPITestCase):
@classmethod
def setUpTestData(cls): # NOQA:N802
"""Create test data."""
super().setUpTestData()
factories.populate_database()
cls.da_token = Token.objects.create(
user=core_models.User.objects.get(username="admin@test.com"))
def test_create(self):
url = reverse("v2:domain-list")
data = {
"name": "domain.tld",
"domain_admin": {
"username": "admin",
"with_mailbox": True,
"with_aliases": True
}
}
resp = self.client.post(url, data, format="json")
self.assertEqual(resp.status_code, 201)
dom = models.Domain.objects.get(pk=resp.json()["pk"])
self.assertEqual(len(dom.admins), 1)
admin = dom.admins.first()
self.assertTrue(hasattr(admin, "mailbox"))
self.assertTrue(
models.Alias.objects.filter(
address="postmaster@domain.tld").exists()
)
def test_delete(self):
self.client.credentials(
HTTP_AUTHORIZATION="Token " + self.da_token.key)
domain = models.Domain.objects.get(name="test2.com")
url = reverse("v2:domain-delete", args=[domain.pk])
resp = self.client.post(url)
self.assertEqual(resp.status_code, 403)
domain = models.Domain.objects.get(name="test.com")
url = reverse("v2:domain-delete", args=[domain.pk])
resp = self.client.post(url)
self.assertEqual(resp.status_code, 403)
self.client.credentials(HTTP_AUTHORIZATION="Token " + self.token.key)
url = reverse("v2:domain-delete", args=[domain.pk])
resp = self.client.post(url)
self.assertEqual(resp.status_code, 204)
def test_administrators(self):
domain = models.Domain.objects.get(name="test.com")
url = reverse("v2:domain-administrators", args=[domain.pk])
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)
self.assertEqual(len(resp.json()), 1)
def test_administrator(self):
domain = models.Domain.objects.get(name="test.com")
url = reverse("v2:domain-add-administrator", args=[domain.pk])
account = core_models.User.objects.get(username="user@test.com")
data = {"account": account.pk}
resp = self.client.post(url, data, format="json")
self.assertEqual(resp.status_code, 200)
def test_remove_adminstrator(self):
domain = models.Domain.objects.get(name="test.com")
url = reverse("v2:domain-remove-administrator", args=[domain.pk])
account = core_models.User.objects.get(username="user@test.com")
data = {"account": account.pk}
resp = self.client.post(url, data, format="json")
self.assertEqual(resp.status_code, 200)
class AccountViewSetTestCase(ModoAPITestCase):
@classmethod
def setUpTestData(cls): # NOQA:N802
"""Create test data."""
super().setUpTestData()
factories.populate_database()
def test_create(self):
url = reverse("v2:account-list")
data = {
"username": "toto@test.com",
"role": "SimpleUsers",
"mailbox": {
"use_domain_quota": True
},
"password": "Toto12345",
"language": "fr",
"aliases": ["alias3@test.com"]
}
resp = self.client.post(url, data, format="json")
self.assertEqual(resp.status_code, 201)
self.assertTrue(
models.Alias.objects.filter(
address="alias3@test.com").exists()
)
def test_create_admin(self):
url = reverse("v2:account-list")
data = {
"username": "superadmin",
"role": "SuperAdmins",
"password": "Toto12345",
"language": "fr",
"aliases": ["alias3@test.com"]
}
resp = self.client.post(url, data, format="json")
self.assertEqual(resp.status_code, 400)
def test_create_with_bad_password(self):
url = reverse("v2:account-list")
data = {
"username": "superadmin",
"role": "SuperAdmins",
}
resp = self.client.post(url, data, format="json")
self.assertEqual(resp.status_code, 400)
self.assertIn("password", resp.json())
data["password"] = "Toto"
resp = self.client.post(url, data, format="json")
self.assertEqual(resp.status_code, 400)
self.assertIn("password", resp.json())
def test_validate(self):
data = {"username": "toto@test.com"}
url = reverse("v2:account-validate")
resp = self.client.post(url, data, format="json")
self.assertEqual(resp.status_code, 204)
def test_random_password(self):
url = reverse("v2:account-random-password")
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)
self.assertIn("password", resp.json())
def test_delete(self):
account = core_models.User.objects.get(username="user@test.com")
url = reverse("v2:account-delete", args=[account.pk])
resp = self.client.post(url)
self.assertEqual(resp.status_code, 204)
with self.assertRaises(core_models.User.DoesNotExist):
account.refresh_from_db()
class IdentityViewSetTestCase(ModoAPITestCase):
@classmethod
def setUpTestData(cls): # NOQA:N802
"""Create test data."""
super().setUpTestData()
factories.populate_database()
def test_list(self):
url = reverse("v2:identities-list")
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)
self.assertEqual(len(resp.json()), 8)
class AliasViewSetTestCase(ModoAPITestCase):
@classmethod
def setUpTestData(cls): # NOQA:N802
"""Create test data."""
super().setUpTestData()
factories.populate_database()
def test_validate(self):
url = reverse("v2:alias-validate")
data = {"address": "alias@unknown.com"}
resp = self.client.post(url, data, format="json")
self.assertEqual(resp.status_code, 400)
data = {"address": "alias@test.com"}
resp = self.client.post(url, data, format="json")
self.assertEqual(resp.status_code, 400)
data = {"address": "alias2@test.com"}
resp = self.client.post(url, data, format="json")
self.assertEqual(resp.status_code, 204)
def test_random_address(self):
url = reverse("v2:alias-random-address")
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)
self.assertIn("address", resp.json())
+1 -1
View File
@@ -32,7 +32,7 @@ def validate_alias_address(address, creator, internal=False, instance=None):
raise ValidationError(_("Domain not found."))
if not creator.can_access(domain):
raise ValidationError(_("Permission denied."))
if instance and instance.address != address:
if not instance or instance.address != address:
if Alias.objects.filter(address=address, internal=internal).exists():
raise ValidationError(_("An alias with this name already exists."))
if instance is None:
+42
View File
@@ -0,0 +1,42 @@
"""API v2 tests."""
from django.urls import reverse
from modoboa.admin import factories as admin_factories
from modoboa.admin import models as admin_models
from modoboa.dnstools import factories
from modoboa.lib.tests import ModoAPITestCase
class DNSViewSetTestCase(ModoAPITestCase):
@classmethod
def setUpTestData(cls): # NOQA:N802
"""Create test data."""
super().setUpTestData()
admin_factories.populate_database()
cls.spf_rec = factories.DNSRecordFactory(
type="spf", value="v=SPF1 mx -all", is_valid=True,
domain__name="test.com"
)
cls.dmarc_rec = factories.DNSRecordFactory(
type="dmarc", value="XXX", is_valid=False,
error="Not a DMARC record",
domain__name="test.com"
)
cls.dkim_rec = factories.DNSRecordFactory(
type="dkim", value="12345", is_valid=False,
error="Public key mismatchs",
domain__name="test.com"
)
cls.ac_rec = factories.DNSRecordFactory(
type="autoconfig", value="1.2.3.4", is_valid=True,
domain__name="test.com"
)
def test_dns_detail(self):
domain = admin_models.Domain.objects.get(name="test.com")
url = reverse("v2:dns-dns-detail", args=[domain.pk])
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)
self.assertEqual(resp.json()["dmarc_record"]["type"], "dmarc")
+25
View File
@@ -0,0 +1,25 @@
"""API v2 tests."""
from django.urls import reverse
from modoboa.lib.tests import ModoAPITestCase
class StatisticsViewSetTestCase(ModoAPITestCase):
def test_list(self):
url = reverse("v2:statistics-list")
resp = self.client.get(url + "?gset=mailtraffic&period=day")
self.assertEqual(resp.status_code, 200)
resp = self.client.get(
url +
"?gset=mailtraffic&period=custom&start=2021-05-01"
)
self.assertEqual(resp.status_code, 400)
resp = self.client.get(
url +
"?gset=mailtraffic&period=custom&start=2021-05-01&end=2021-05-02"
)
self.assertEqual(resp.status_code, 200)