mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-19 05:58:34 +02:00
253 lines
9.0 KiB
Python
253 lines
9.0 KiB
Python
"""Tests for core application."""
|
|
|
|
from io import StringIO
|
|
|
|
import httmock
|
|
from dateutil.relativedelta import relativedelta
|
|
|
|
from django.core import mail
|
|
from django.core import management
|
|
from django.test import TestCase
|
|
from django.urls import reverse
|
|
from django.utils import timezone
|
|
|
|
from modoboa.lib.tests import ModoTestCase
|
|
from .. import factories, mocks, models
|
|
|
|
|
|
class AuthenticationTestCase(ModoTestCase):
|
|
|
|
"""Validate authentication scenarios."""
|
|
|
|
@classmethod
|
|
def setUpTestData(cls): # NOQA:N802
|
|
"""Create test data."""
|
|
super(AuthenticationTestCase, cls).setUpTestData()
|
|
cls.account = factories.UserFactory(
|
|
username="user@test.com", groups=("SimpleUsers",)
|
|
)
|
|
|
|
def test_authentication(self):
|
|
"""Validate simple case."""
|
|
self.client.logout()
|
|
data = {"username": "user@test.com", "password": "toto"}
|
|
response = self.client.post(reverse("core:login"), data)
|
|
self.assertEqual(response.status_code, 302)
|
|
self.assertTrue(response.url.endswith(reverse("core:user_index")))
|
|
|
|
response = self.client.post(reverse("core:logout"), {})
|
|
self.assertEqual(response.status_code, 302)
|
|
|
|
data = {"username": "admin", "password": "password"}
|
|
response = self.client.post(reverse("core:login"), data)
|
|
self.assertEqual(response.status_code, 302)
|
|
self.assertTrue(response.url.endswith(reverse("core:dashboard")))
|
|
|
|
|
|
class ManagementCommandsTestCase(TestCase):
|
|
"""Test management commands."""
|
|
|
|
def test_change_default_admin(self):
|
|
"""Use dedicated option."""
|
|
management.call_command(
|
|
"load_initial_data", "--admin-username", "modoadmin")
|
|
self.assertTrue(
|
|
self.client.login(username="modoadmin", password="password"))
|
|
|
|
def test_clean_logs(self):
|
|
"""Run cleanlogs command."""
|
|
log1 = factories.LogFactory()
|
|
factories.LogFactory()
|
|
log1.date_created -= relativedelta(years=2)
|
|
log1.save(update_fields=["date_created"])
|
|
management.call_command("cleanlogs")
|
|
self.assertEqual(models.Log.objects.count(), 1)
|
|
|
|
def test_clean_inactive_accounts(self):
|
|
"""Run clean_inactive_accounts command."""
|
|
management.call_command("load_initial_data")
|
|
|
|
# no inactive account, should exit normaly
|
|
management.call_command("clean_inactive_accounts")
|
|
|
|
last_login = timezone.now() - relativedelta(days=45)
|
|
account = factories.UserFactory(
|
|
username="user1@domain.test", groups=("SimpleUsers", ),
|
|
last_login=last_login
|
|
)
|
|
management.call_command("clean_inactive_accounts", "--dry-run")
|
|
account.refresh_from_db()
|
|
self.assertTrue(account.is_active)
|
|
|
|
out = StringIO()
|
|
management.call_command(
|
|
"clean_inactive_accounts", "--verbose", "--dry-run", stdout=out)
|
|
self.assertIn("user1@domain.test", out.getvalue())
|
|
|
|
management.call_command("clean_inactive_accounts", "--silent")
|
|
account.refresh_from_db()
|
|
self.assertFalse(account.is_active)
|
|
|
|
account.is_active = True
|
|
account.save(update_fields=["is_active"])
|
|
|
|
management.call_command(
|
|
"clean_inactive_accounts", "--silent", "--delete")
|
|
with self.assertRaises(models.User.DoesNotExist):
|
|
account.refresh_from_db()
|
|
|
|
|
|
class ProfileTestCase(ModoTestCase):
|
|
"""Profile related tests."""
|
|
|
|
@classmethod
|
|
def setUpTestData(cls): # NOQA:N802
|
|
"""Create test data."""
|
|
super(ProfileTestCase, cls).setUpTestData()
|
|
cls.account = factories.UserFactory(
|
|
username="user@test.com", groups=("SimpleUsers",)
|
|
)
|
|
|
|
def test_update_profile(self):
|
|
"""Update profile without password."""
|
|
data = {
|
|
"first_name": "Homer", "last_name": "Simpson",
|
|
"phone_number": "+33612345678", "language": "en"
|
|
}
|
|
self.ajax_post(reverse("core:user_profile"), data)
|
|
admin = models.User.objects.get(username="admin")
|
|
self.assertEqual(admin.last_name, "Simpson")
|
|
|
|
def test_update_password(self):
|
|
"""Password update
|
|
|
|
Two cases:
|
|
* The default admin changes his password (no associated Mailbox)
|
|
* A normal user changes his password
|
|
"""
|
|
self.ajax_post(reverse("core:user_profile"),
|
|
{"language": "en", "oldpassword": "password",
|
|
"newpassword": "12345Toi", "confirmation": "12345Toi"})
|
|
self.client.logout()
|
|
|
|
self.assertEqual(
|
|
self.client.login(username="admin", password="12345Toi"), True
|
|
)
|
|
self.assertEqual(
|
|
self.client.login(username="user@test.com", password="toto"), True
|
|
)
|
|
|
|
self.ajax_post(
|
|
reverse("core:user_profile"),
|
|
{"oldpassword": "toto",
|
|
"newpassword": "tutu", "confirmation": "tutu"},
|
|
status=400
|
|
)
|
|
|
|
self.ajax_post(
|
|
reverse("core:user_profile"),
|
|
{"language": "en", "oldpassword": "toto",
|
|
"newpassword": "Toto1234", "confirmation": "Toto1234"}
|
|
)
|
|
self.client.logout()
|
|
self.assertTrue(
|
|
self.client.login(username="user@test.com", password="Toto1234")
|
|
)
|
|
|
|
def test_update_password_url(self):
|
|
"""Check if external is used when defined."""
|
|
self.set_global_parameter(
|
|
"update_password_url", "http://update.password")
|
|
non_local_user = factories.UserFactory(
|
|
username="user@external.com", groups=("SimpleUsers",),
|
|
is_local=False
|
|
)
|
|
self.client.force_login(non_local_user)
|
|
url = reverse("core:user_profile")
|
|
response = self.client.get(url)
|
|
self.assertContains(response, "http://update.password")
|
|
|
|
self.client.force_login(self.account)
|
|
response = self.client.get(url)
|
|
self.assertNotContains(response, "http://update.password")
|
|
|
|
|
|
class APIAccessFormTestCase(ModoTestCase):
|
|
|
|
"""Check form access."""
|
|
|
|
@classmethod
|
|
def setUpTestData(cls): # NOQA:N802
|
|
"""Create test data."""
|
|
super(APIAccessFormTestCase, cls).setUpTestData()
|
|
cls.account = factories.UserFactory(
|
|
username="user@test.com", groups=("SimpleUsers",)
|
|
)
|
|
|
|
def test_form_access(self):
|
|
"""Check access restrictions."""
|
|
url = reverse("core:user_api_access")
|
|
self.ajax_get(url)
|
|
self.client.logout()
|
|
self.client.login(username="user@test.com", password="toto")
|
|
response = self.client.get(url, HTTP_X_REQUESTED_WITH="XMLHttpRequest")
|
|
self.assertEqual(response.status_code, 278)
|
|
|
|
def test_form(self):
|
|
"""Check that token is created/removed."""
|
|
url = reverse("core:user_api_access")
|
|
self.ajax_post(url, {"enable_api_access": True})
|
|
user = models.User.objects.get(username="admin")
|
|
self.assertTrue(hasattr(user, "auth_token"))
|
|
self.ajax_post(url, {"enable_api_access": False})
|
|
user = models.User.objects.get(username="admin")
|
|
self.assertFalse(hasattr(user, "auth_token"))
|
|
|
|
|
|
class APICommunicationTestCase(ModoTestCase):
|
|
"""Check communication with the API."""
|
|
|
|
def test_management_command(self):
|
|
"""Check command."""
|
|
with httmock.HTTMock(
|
|
mocks.modo_api_instance_search,
|
|
mocks.modo_api_instance_create,
|
|
mocks.modo_api_instance_update,
|
|
mocks.modo_api_versions):
|
|
management.call_command("communicate_with_public_api")
|
|
self.assertEqual(models.LocalConfig.objects.first().api_pk, 100)
|
|
self.assertEqual(len(mail.outbox), 0)
|
|
|
|
url = reverse("core:information")
|
|
response = self.ajax_request("get", url)
|
|
self.assertIn("9.0.0", response["content"])
|
|
|
|
# Enable notifications
|
|
self.set_global_parameter("send_new_versions_email", True)
|
|
with httmock.HTTMock(
|
|
mocks.modo_api_instance_search,
|
|
mocks.modo_api_instance_create,
|
|
mocks.modo_api_instance_update,
|
|
mocks.modo_api_versions):
|
|
management.call_command("communicate_with_public_api")
|
|
self.assertEqual(len(mail.outbox), 1)
|
|
|
|
# Call once again and check no new notification has been sent
|
|
self.set_global_parameter("send_new_versions_email", True)
|
|
with httmock.HTTMock(
|
|
mocks.modo_api_instance_search,
|
|
mocks.modo_api_instance_create,
|
|
mocks.modo_api_instance_update,
|
|
mocks.modo_api_versions):
|
|
management.call_command("communicate_with_public_api")
|
|
self.assertEqual(len(mail.outbox), 1)
|
|
|
|
# Make sure no new notification is sent when no updates
|
|
with httmock.HTTMock(
|
|
mocks.modo_api_instance_search,
|
|
mocks.modo_api_instance_create,
|
|
mocks.modo_api_instance_update,
|
|
mocks.modo_api_versions_no_update):
|
|
management.call_command("communicate_with_public_api")
|
|
self.assertEqual(len(mail.outbox), 1)
|