mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
Removed deprecated tests
This commit is contained in:
@@ -55,20 +55,10 @@ class AuthenticationTestCase(ModoTestCase):
|
||||
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")))
|
||||
session = self.client.session
|
||||
self.assertIn("password", session)
|
||||
|
||||
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")))
|
||||
session = self.client.session
|
||||
self.assertNotIn("password", session)
|
||||
|
||||
@mock.patch("django_otp.match_token")
|
||||
@mock.patch("django_otp.login")
|
||||
def test_authentication_with_2fa(self, login_mock, match_mock):
|
||||
@@ -87,26 +77,17 @@ class AuthenticationTestCase(ModoTestCase):
|
||||
self.assertContains(response, "This code is invalid")
|
||||
response = self.client.post(url, data)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
session = self.client.session
|
||||
self.assertIn("password", session)
|
||||
|
||||
def test_open_redirect(self):
|
||||
"""Check that open redirect is not allowed."""
|
||||
self.client.logout()
|
||||
data = {"username": "admin", "password": "password"}
|
||||
|
||||
# 1. Check valid redirection
|
||||
url = "{}?next=/admin/".format(reverse("core:login"))
|
||||
response = self.client.post(url, data)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertTrue(response.url.endswith(reverse("admin:index")))
|
||||
self.client.logout()
|
||||
|
||||
# 2. Check bad redirection
|
||||
url = "{}?next=http://www.evil.com".format(reverse("core:login"))
|
||||
response = self.client.post(url, data)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertTrue(response.url.endswith(reverse("core:dashboard")))
|
||||
self.assertEqual(response.url, "/")
|
||||
|
||||
@override_settings(DOVEADM_LOOKUP_PATH=[DOVEADM_TEST_PATH])
|
||||
def test_password_schemes(self):
|
||||
|
||||
@@ -32,7 +32,6 @@ class AuthenticationTestCase(ModoTestCase):
|
||||
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)
|
||||
@@ -40,7 +39,6 @@ class AuthenticationTestCase(ModoTestCase):
|
||||
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(SimpleModoTestCase):
|
||||
@@ -109,153 +107,6 @@ class ManagementCommandsTestCase(SimpleModoTestCase):
|
||||
account.refresh_from_db()
|
||||
|
||||
|
||||
class ProfileTestCase(ModoTestCase):
|
||||
"""Profile related tests."""
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls): # NOQA:N802
|
||||
"""Create test data."""
|
||||
super().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"),
|
||||
{"language": "en", "oldpassword": "toto", "confirmation": "tutu"},
|
||||
status=400,
|
||||
)
|
||||
|
||||
self.ajax_post(
|
||||
reverse("core:user_profile"),
|
||||
{"language": "en", "oldpassword": "toto", "newpassword": "tutu"},
|
||||
status=400,
|
||||
)
|
||||
|
||||
self.ajax_post(
|
||||
reverse("core:user_profile"),
|
||||
{
|
||||
"language": "en",
|
||||
"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_restrictions(self):
|
||||
self.ajax_post(
|
||||
reverse("core:user_profile"),
|
||||
{
|
||||
"language": "en",
|
||||
"oldpassword": "",
|
||||
"newpassword": "12345Toi",
|
||||
"confirmation": "12345Toi",
|
||||
},
|
||||
status=400,
|
||||
)
|
||||
self.client.logout()
|
||||
|
||||
self.assertEqual(
|
||||
self.client.login(username="admin", password="12345Toi"), False
|
||||
)
|
||||
|
||||
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().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."""
|
||||
|
||||
@@ -271,10 +122,6 @@ class APICommunicationTestCase(ModoTestCase):
|
||||
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(
|
||||
|
||||
@@ -1,349 +0,0 @@
|
||||
"""Core views test cases."""
|
||||
|
||||
from testfixtures import compare
|
||||
|
||||
from django import forms
|
||||
from django.urls import reverse
|
||||
from django.test import override_settings
|
||||
|
||||
from modoboa.lib.tests import ModoTestCase
|
||||
from modoboa.parameters import forms as param_forms, tools as param_tools
|
||||
from .. import factories, models, signals
|
||||
|
||||
SETTINGS_SAMPLE = {
|
||||
"core-check_new_versions": "True",
|
||||
"core-log_maximum_age": "365",
|
||||
"core-ldap_auth_method": "searchbind",
|
||||
"limits-deflt_domain_mailbox_aliases_limit": "0",
|
||||
"core-send_statistics": "True",
|
||||
"core-default_top_redirection": "user",
|
||||
"core-sender_address": "noreply@modoboa.org",
|
||||
"admin-auto_account_removal": "False",
|
||||
"core-ldap_server_port": "389",
|
||||
"core-rounds_number": "70000",
|
||||
"core-ldap_bind_password": "",
|
||||
"limits-deflt_domain_domain_aliases_limit": "0",
|
||||
"core-secret_key": ":?j3]QPWo!.'_c4n",
|
||||
"limits-deflt_domain_domain_admins_limit": "0",
|
||||
"limits-enable_admin_limits": "True",
|
||||
"core-ldap_bind_dn": "",
|
||||
"core-enable_api_communication": "True",
|
||||
"limits-deflt_user_domain_admins_limit": "0",
|
||||
"limits-enable_domain_limits": "False",
|
||||
"csrfmiddlewaretoken": "SGgMVZsA4TPqoiV786TMST6xgOlhAf4F",
|
||||
"limits-deflt_user_mailboxes_limit": "0",
|
||||
"core-password_scheme": "plain",
|
||||
"core-update_scheme": True,
|
||||
"core-items_per_page": "30",
|
||||
"limits-deflt_user_mailbox_aliases_limit": "0",
|
||||
"limits-deflt_domain_mailboxes_limit": "0",
|
||||
"core-ldap_is_active_directory": "False",
|
||||
"core-ldap_group_type": "posixgroup",
|
||||
"limits-deflt_user_domain_aliases_limit": "0",
|
||||
"core-top_notifications_check_interval": "30",
|
||||
"core-ldap_password_attribute": "userPassword",
|
||||
"admin-auto_create_domain_and_mailbox": "True",
|
||||
"admin-enable_dnsbl_checks": "True",
|
||||
"admin-default_domain_quota": "0",
|
||||
"admin-default_mailbox_quota": "0",
|
||||
"core-ldap_server_address": "localhost",
|
||||
"core-authentication_type": "local",
|
||||
"core-ldap_admin_groups": "",
|
||||
"core-ldap_groups_search_base": "",
|
||||
"admin-enable_mx_checks": "True",
|
||||
"admin-enable_ipv6_mx_checks": "True",
|
||||
"core-ldap_search_base": "",
|
||||
"admin-valid_mxs": "",
|
||||
"limits-deflt_user_domains_limit": "0",
|
||||
"core-ldap_search_filter": "(mail=%(user)s)",
|
||||
"core-ldap_secured": "none",
|
||||
"core-ldap_user_dn_template": "",
|
||||
"core-default_password": "Toto1000",
|
||||
"limits-deflt_user_quota_limit": "0",
|
||||
"core-hide_features_widget": "False",
|
||||
"core-enable_inactive_accounts": "True",
|
||||
"core-inactive_account_threshold": "30",
|
||||
"admin-domains_must_have_authorized_mx": False,
|
||||
"core-random_password_length": "8",
|
||||
"admin-create_alias_on_mbox_rename": False,
|
||||
"admin-dkim_keys_storage_dir": "",
|
||||
"admin-dkim_default_key_length": 1024,
|
||||
"admin-custom_dns_server": "193.43.55.67",
|
||||
"admin-enable_spf_checks": True,
|
||||
"admin-enable_dkim_checks": True,
|
||||
"admin-enable_dmarc_checks": True,
|
||||
"admin-enable_autoconfig_checks": True,
|
||||
"core-ldap_enable_sync": False,
|
||||
"core-ldap_sync_bind_dn": "",
|
||||
"core-ldap_sync_bind_password": "",
|
||||
"core-ldap_sync_account_dn_template": "",
|
||||
"core-ldap_sync_delete_remote_account": False,
|
||||
"core-send_new_versions_email": False,
|
||||
"core-new_versions_email_rcpt": "postmaster@domain.test",
|
||||
"core-ldap_enable_secondary_server": False,
|
||||
"core-ldap_secondary_server_address": "localhost",
|
||||
"core-ldap_secondary_server_port": 389,
|
||||
"core-ldap_enable_import": False,
|
||||
"core-ldap_import_search_base": "",
|
||||
"core-ldap_import_search_filter": "",
|
||||
"core-ldap_import_username_attr": "cn",
|
||||
"core-sms_password_recovery": False,
|
||||
"core-sms_provider": "",
|
||||
"core-sms_ovh_endpoint": "ovh-eu",
|
||||
"core-password_recovery_msg": "",
|
||||
"core-ldap_dovecot_sync": False,
|
||||
"maillog-logfile": "/var/log/mail.log",
|
||||
"maillog-rrd_rootdir": "/tmp",
|
||||
"maillog-greylist": False,
|
||||
"pdfcredentials-enabled_pdfcredentials": True,
|
||||
"pdfcredentials-storage_dir": "./",
|
||||
"pdfcredentials-delete_first_dl": True,
|
||||
"pdfcredentials-generate_at_creation": True,
|
||||
"pdfcredentials-title": "Modoboa",
|
||||
"pdfcredentials-webpanel_url": "local.host/",
|
||||
"pdfcredentials-custom_message": "test",
|
||||
"pdfcredentials-include_connection_settings": False,
|
||||
"pdfcredentials-smtp_server_address": "127.0.0.1",
|
||||
"pdfcredentials-smtp_server_port": 666,
|
||||
"pdfcredentials-smtp_connection_security": "starttls",
|
||||
"pdfcredentials-imap_server_address": "127.0.0.1",
|
||||
"pdfcredentials-imap_server_port": 667,
|
||||
"pdfcredentials-imap_connection_security": "starttls",
|
||||
"dmarc-enable_rlookups": False,
|
||||
"imap_migration-enabled_imapmigration": True,
|
||||
"imap_migration-max_sync_accounts": 2,
|
||||
"imap_migration-create_folders": True,
|
||||
"postfix_autoreply-autoreplies_timeout": 86400,
|
||||
"postfix_autoreply-default_subject": "I'm off",
|
||||
"postfix_autoreply-default_content": "I'm off",
|
||||
"sievefilters-server": "127.0.0.1",
|
||||
"sievefilters-port": 4190,
|
||||
"sievefilters-starttls": False,
|
||||
"sievefilters-authentication_mech": "AUTO",
|
||||
"sievefilters-imap_server": "127.0.0.1",
|
||||
"sievefilters-imap_secured": False,
|
||||
"sievefilters-imap_port": 143,
|
||||
}
|
||||
|
||||
|
||||
def announcement(sender, location, **kwargs):
|
||||
"""Simpler handler."""
|
||||
return "This is an annoucement!"
|
||||
|
||||
|
||||
class LoginTestCase(ModoTestCase):
|
||||
"""Login page test cases."""
|
||||
|
||||
def test_announcements(self):
|
||||
"""Check if announcements are displayed."""
|
||||
signals.get_announcements.connect(announcement)
|
||||
response = self.client.get(reverse("core:login"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertIn("This is an annoucement!", str(response.content))
|
||||
|
||||
|
||||
class DashboardTestCase(ModoTestCase):
|
||||
"""Dashboard tests."""
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls): # NOQA:N802
|
||||
"""Create some data."""
|
||||
super().setUpTestData()
|
||||
cls.dadmin = factories.UserFactory(
|
||||
username="admin@test.com", groups=("DomainAdmins",)
|
||||
)
|
||||
cls.user = factories.UserFactory(
|
||||
username="user@test.com", groups=("SimpleUsers",)
|
||||
)
|
||||
|
||||
def test_access(self):
|
||||
"""Load dashboard."""
|
||||
url = reverse("core:dashboard")
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertIn("Latest news", response.content.decode("utf-8"))
|
||||
self.client.logout()
|
||||
self.client.login(username=self.dadmin.username, password="toto")
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertIn("Latest news", response.content.decode("utf-8"))
|
||||
self.client.logout()
|
||||
self.client.login(username=self.user.username, password="toto")
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_custom_news(self):
|
||||
"""Check that custom news are displayed."""
|
||||
url = reverse("core:dashboard")
|
||||
response = self.client.get(url)
|
||||
self.assertContains(response, "https://modoboa.org")
|
||||
|
||||
self.set_global_parameter(
|
||||
"rss_feed_url", "https://www.djangoproject.com/rss/weblog/"
|
||||
)
|
||||
self.client.force_login(self.dadmin)
|
||||
response = self.client.get(url)
|
||||
self.assertContains(response, "djangoproject")
|
||||
|
||||
def test_features_visibility(self):
|
||||
"""Hide or not features widget."""
|
||||
url = reverse("core:dashboard")
|
||||
response = self.client.get(url)
|
||||
self.assertContains(response, "Features looking for sponsoring")
|
||||
|
||||
self.client.force_login(self.dadmin)
|
||||
response = self.client.get(url)
|
||||
self.assertContains(response, "Features looking for sponsoring")
|
||||
|
||||
self.set_global_parameter("hide_features_widget", True)
|
||||
response = self.client.get(url)
|
||||
self.assertNotContains(response, "Features looking for sponsoring")
|
||||
|
||||
@override_settings(DISABLE_DASHBOARD_EXTERNAL_QUERIES=False)
|
||||
def test_enable_dashboard_external_queries(self):
|
||||
"""Load dashboard with DISABLE_DASHBOARD_EXTERNAL_QUERIES = False"""
|
||||
url = reverse("core:dashboard")
|
||||
response = self.client.get(url)
|
||||
self.assertContains(response, 'href="https://modoboa.org/en/weblog/')
|
||||
|
||||
@override_settings(DISABLE_DASHBOARD_EXTERNAL_QUERIES=True)
|
||||
def test_disable_dashboard_external_queries(self):
|
||||
"""Load dashboard with DISABLE_DASHBOARD_EXTERNAL_QUERIES = True"""
|
||||
url = reverse("core:dashboard")
|
||||
response = self.client.get(url)
|
||||
self.assertNotContains(response, "https://modoboa.org/en/weblog/")
|
||||
|
||||
def test_root_dispatch(self):
|
||||
"""Check root dispatching."""
|
||||
url = reverse("core:root")
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertTrue(response.url.endswith(reverse("core:dashboard")))
|
||||
|
||||
def test_top_notifications(self):
|
||||
"""Check top notifications service."""
|
||||
url = reverse("core:top_notifications_check")
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(response.json()), 1)
|
||||
|
||||
|
||||
class SettingsTestCase(ModoTestCase):
|
||||
"""Settings tests."""
|
||||
|
||||
def test_get_settings(self):
|
||||
"""Test settings display."""
|
||||
url = reverse("core:parameters")
|
||||
response = self.ajax_get(url)
|
||||
for app in ["core", "admin", "limits"]:
|
||||
self.assertIn(f'data-app="{app}"', response["content"])
|
||||
|
||||
def test_save_settings(self):
|
||||
"""Test settings save."""
|
||||
url = reverse("core:parameters")
|
||||
settings = SETTINGS_SAMPLE.copy()
|
||||
response = self.client.post(url, settings, format="json")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
settings["core-password_scheme"] = "magic_password_scheme"
|
||||
response = self.client.post(url, settings, format="json")
|
||||
self.assertEqual(response.status_code, 400)
|
||||
compare(
|
||||
response.json(),
|
||||
{
|
||||
"form_errors": {
|
||||
"password_scheme": [
|
||||
"Select a valid choice. \
|
||||
magic_password_scheme is not one of the available choices."
|
||||
]
|
||||
},
|
||||
"prefix": "core",
|
||||
},
|
||||
)
|
||||
settings["core-password_scheme"] = "plain"
|
||||
settings["core-rounds_number"] = ""
|
||||
response = self.client.post(url, settings, format="json")
|
||||
self.assertEqual(response.status_code, 400)
|
||||
compare(
|
||||
response.json(),
|
||||
{
|
||||
"form_errors": {"rounds_number": ["This field is required."]},
|
||||
"prefix": "core",
|
||||
},
|
||||
)
|
||||
|
||||
def test_sms_settings_clean(self):
|
||||
"""Check sms settings validation."""
|
||||
url = reverse("core:parameters")
|
||||
settings = SETTINGS_SAMPLE.copy()
|
||||
settings["core-sms_password_recovery"] = True
|
||||
settings["core-sms_provider"] = ""
|
||||
response = self.client.post(url, settings, format="json")
|
||||
self.assertEqual(response.status_code, 400)
|
||||
settings["core-sms_provider"] = "ovh"
|
||||
response = self.client.post(url, settings, format="json")
|
||||
self.assertEqual(response.status_code, 400)
|
||||
errors = response.json()
|
||||
self.assertIn("sms_ovh_application_secret", errors["form_errors"])
|
||||
|
||||
def test_mx_check_settings_clean(self):
|
||||
settings = SETTINGS_SAMPLE.copy()
|
||||
settings["admin-enable_mx_checks"] = False
|
||||
url = reverse("core:parameters")
|
||||
response = self.client.post(url, settings, format="json")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertFalse(
|
||||
param_tools.get_global_parameter("enable_ipv6_mx_checks", "admin")
|
||||
)
|
||||
|
||||
|
||||
class UserSettings(param_forms.UserParametersForm):
|
||||
"""Stupid user settings form."""
|
||||
|
||||
app = "core"
|
||||
|
||||
test = forms.CharField()
|
||||
|
||||
|
||||
def extra_user_menu(sender, location, user, **kwargs):
|
||||
"""Return extra menu entry."""
|
||||
return [
|
||||
{"name": "test_menu_entry", "class": "ajaxnav", "url": "toto/", "label": "Test"}
|
||||
]
|
||||
|
||||
|
||||
class PreferencesTestCase(ModoTestCase):
|
||||
"""Test user preferences."""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
"""Register user form."""
|
||||
super().setUpClass()
|
||||
param_tools.registry.add("user", UserSettings, "Test")
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
"""Remove user class."""
|
||||
super().tearDownClass()
|
||||
del param_tools.registry._registry["user"]["core"]
|
||||
|
||||
def test_get_user_index(self):
|
||||
"""Retrieve index page."""
|
||||
signals.extra_user_menu_entries.connect(extra_user_menu)
|
||||
url = reverse("core:user_index")
|
||||
response = self.client.get(url)
|
||||
self.assertContains(response, 'name="test_menu_entry"')
|
||||
|
||||
def test_get_preferences(self):
|
||||
"""Test preferences display."""
|
||||
url = reverse("core:user_preferences")
|
||||
self.ajax_get(url)
|
||||
|
||||
def test_save_preferences(self):
|
||||
"""Test preferences save."""
|
||||
url = reverse("core:user_preferences")
|
||||
response = self.client.post(url, {"core-test": "toto"}, format="json")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.json(), "Preferences saved")
|
||||
|
||||
admin = models.User.objects.get(username="admin")
|
||||
self.assertEqual(admin.parameters.get_value("test"), "toto")
|
||||
@@ -1,78 +0,0 @@
|
||||
"""API viewsets test cases."""
|
||||
|
||||
from unittest import mock
|
||||
|
||||
from django.urls import reverse
|
||||
|
||||
from modoboa.admin import factories as admin_factories
|
||||
from modoboa.lib.tests import ModoAPITestCase
|
||||
|
||||
from .. import models
|
||||
|
||||
|
||||
class AccountViewSetTestCase(ModoAPITestCase):
|
||||
"""Account viewset tests."""
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
super().setUpTestData()
|
||||
admin_factories.populate_database()
|
||||
|
||||
@mock.patch("django_otp.plugins.otp_totp.models.TOTPDevice.verify_token")
|
||||
def test_tfa_setup_process(self, verify_mock, password_ok="password"):
|
||||
admin = models.User.objects.get(username="admin")
|
||||
self.client.force_login(admin)
|
||||
|
||||
# First, check if we're in the initial state
|
||||
security_url = reverse("core:user_security")
|
||||
response = self.client.get(security_url)
|
||||
self.assertIn("not yet activated for", response.json()["content"])
|
||||
|
||||
# Start setup sequence
|
||||
url = reverse("v1:account-tfa-setup")
|
||||
response = self.client.post(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# Check if security page is up-to-date
|
||||
security_url = reverse("core:user_security")
|
||||
response = self.client.get(security_url)
|
||||
self.assertIn("FreeOTP", response.json()["content"])
|
||||
|
||||
# Continue setup sequence
|
||||
verify_mock.side_effect = [True]
|
||||
url = reverse("v1:account-tfa-setup-check")
|
||||
data = {"pin_code": "1234"}
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# Display recovery tokens
|
||||
security_url = reverse("core:user_security")
|
||||
response = self.client.get(security_url)
|
||||
|
||||
self.assertIn("recovery codes", response.json()["content"])
|
||||
admin.refresh_from_db()
|
||||
self.assertTrue(admin.totp_enabled)
|
||||
self.assertTrue(admin.tfa_enabled)
|
||||
device = admin.staticdevice_set.first()
|
||||
self.assertIsNot(device, None)
|
||||
self.assertEqual(device.token_set.count(), 10)
|
||||
|
||||
# Try to disable TFA auth
|
||||
url = reverse("api:account-tfa-disable")
|
||||
data = {"password": password_ok}
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertFalse(admin.totpdevice_set.exists())
|
||||
|
||||
def test_tfa_reset_codes(self, password_ok="password"):
|
||||
admin = models.User.objects.get(username="admin")
|
||||
self.client.force_login(admin)
|
||||
url = reverse("api:account-tfa-reset-codes")
|
||||
data = {"password": password_ok}
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
device = admin.staticdevice_set.create(name="Device")
|
||||
response = self.client.post(url, data, format="json")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(device.token_set.count(), 10)
|
||||
@@ -56,11 +56,7 @@ class LoginViewMixin:
|
||||
return None
|
||||
|
||||
def login(self, user, rememberme):
|
||||
encrypted_password = self.request.session.pop("password", None)
|
||||
login(self.request, user)
|
||||
# FIXME: remove ASAP
|
||||
if encrypted_password:
|
||||
self.request.session["password"] = encrypted_password
|
||||
if not rememberme:
|
||||
self.request.session.set_expiry(0)
|
||||
|
||||
@@ -126,12 +122,6 @@ class LoginView(LoginViewMixin, auth_views.LoginView):
|
||||
def form_valid(self, form):
|
||||
user = form.get_user()
|
||||
self.check_password_hash(user, form)
|
||||
# FIXME: remove ASAP
|
||||
signals.user_login.send(
|
||||
sender="LoginView",
|
||||
user=user,
|
||||
password=form.cleaned_data["password"],
|
||||
)
|
||||
if user.tfa_enabled:
|
||||
self.request.session[constants.TFA_PRE_VERIFY_USER_PK] = user.pk
|
||||
self.request.session[constants.TFA_PRE_VERIFY_USER_BACKEND] = user.backend
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
"""Views tests."""
|
||||
|
||||
from django.urls import reverse
|
||||
|
||||
from modoboa.admin import factories as admin_factories
|
||||
from modoboa.core import models as core_models
|
||||
from modoboa.lib.tests import ModoTestCase
|
||||
|
||||
from . import mixins
|
||||
|
||||
|
||||
class DMARCViewsTestCase(mixins.CallCommandMixin, ModoTestCase):
|
||||
"""Views test cases."""
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
"""Create test data."""
|
||||
super().setUpTestData()
|
||||
cls.domain = admin_factories.DomainFactory(name="ngyn.org")
|
||||
|
||||
def test_domainlist_view(self):
|
||||
"""Test domain list view."""
|
||||
self.import_reports()
|
||||
user = core_models.User.objects.get(username="admin")
|
||||
self.client.force_login(user)
|
||||
url = reverse("admin:_domain_list")
|
||||
response = self.ajax_get(url)
|
||||
url = reverse("dmarc:domain_report", args=[self.domain.pk])
|
||||
self.assertIn(url, response["rows"])
|
||||
|
||||
def test_domainreport_view(self):
|
||||
"""Test domain report view."""
|
||||
self.import_reports()
|
||||
user = core_models.User.objects.get(username="admin")
|
||||
self.client.force_login(user)
|
||||
url = reverse("dmarc:domain_report", args=[self.domain.pk])
|
||||
response = self.client.get(f"{url}?period=2015-26")
|
||||
self.assertContains(response, "'Failed', 100.0")
|
||||
|
||||
def test_domainreport_view_week0(self):
|
||||
"""Test domain report view for week 0."""
|
||||
self.import_reports()
|
||||
user = core_models.User.objects.get(username="admin")
|
||||
self.client.force_login(user)
|
||||
url = reverse("dmarc:domain_report", args=[self.domain.pk])
|
||||
response = self.client.get(f"{url}?period=2019-0")
|
||||
self.assertContains(response, "Dec. 31, 2018")
|
||||
|
||||
def test_domainreport_view_week1(self):
|
||||
"""Test domain report view for week 1."""
|
||||
self.import_reports()
|
||||
user = core_models.User.objects.get(username="admin")
|
||||
self.client.force_login(user)
|
||||
url = reverse("dmarc:domain_report", args=[self.domain.pk])
|
||||
response = self.client.get(f"{url}?period=2019-1")
|
||||
self.assertContains(response, "Jan. 7, 2019")
|
||||
|
||||
def test_domainreport_view_week52(self):
|
||||
"""Test domain report view for week 52."""
|
||||
self.import_reports()
|
||||
user = core_models.User.objects.get(username="admin")
|
||||
self.client.force_login(user)
|
||||
url = reverse("dmarc:domain_report", args=[self.domain.pk])
|
||||
response = self.client.get(f"{url}?period=2018-52")
|
||||
self.assertContains(response, "Dec. 30, 2018")
|
||||
|
||||
def test_domainreport_view_arc(self):
|
||||
"""Test domain report view for displaying ARC results"""
|
||||
self.import_reports()
|
||||
user = core_models.User.objects.get(username="admin")
|
||||
self.client.force_login(user)
|
||||
url = reverse("dmarc:domain_report", args=[self.domain.pk])
|
||||
response = self.client.get(f"{url}?period=2021-22")
|
||||
self.assertContains(response, "'Fully aligned', 86.0")
|
||||
self.assertContains(response, "'Partially aligned', 8.0")
|
||||
self.assertContains(response, "'Forwarded', 4.0")
|
||||
self.assertContains(response, "'Failed', 2.0")
|
||||
@@ -34,16 +34,6 @@ class DataMixin:
|
||||
)
|
||||
|
||||
|
||||
# class ViewsTestCase(DataMixin, ModoTestCase):
|
||||
# """Views test cases."""
|
||||
|
||||
# def test_index(self):
|
||||
# """Test index view."""
|
||||
# url = reverse("modoboa_imap_migration:index")
|
||||
# response = self.client.get(url)
|
||||
# self.assertContains(response, '<div id="app">')
|
||||
|
||||
|
||||
class AuthenticationTestCase(DataMixin, ModoTestCase):
|
||||
"""IMAP authentication test case."""
|
||||
|
||||
|
||||
@@ -236,78 +236,6 @@ class EventsTestCase(ModoTestCase):
|
||||
)
|
||||
|
||||
|
||||
class FormTestCase(ModoTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls): # NOQA:N802
|
||||
"""Create test data."""
|
||||
super().setUpTestData()
|
||||
admin_factories.populate_database()
|
||||
|
||||
def setUp(self):
|
||||
"""Initialize tests."""
|
||||
super().setUp()
|
||||
self.client.logout()
|
||||
self.client.login(username="user@test.com", password="toto")
|
||||
|
||||
def test_form_display(self):
|
||||
"""Check if form is displayed."""
|
||||
url = reverse("core:user_index")
|
||||
response = self.client.get(url)
|
||||
self.assertContains(response, "function autoreply_cb()")
|
||||
self.assertContains(response, 'name="autoreply"')
|
||||
|
||||
response = self.ajax_get(reverse("autoreply"))
|
||||
self.assertIn("%(name)s", response["content"])
|
||||
|
||||
def test_set_autoreply(self):
|
||||
values = {"subject": "test", "content": "I'm off", "enabled": True}
|
||||
self.ajax_post(reverse("autoreply"), values)
|
||||
account = User.objects.get(username="user@test.com")
|
||||
arm = models.ARmessage.objects.get(mbox=account.mailbox)
|
||||
self.assertEqual(arm.subject, "test")
|
||||
self.assertTrue(arm.enabled)
|
||||
self.assertFalse(arm.untildate)
|
||||
self.assertTrue(arm.fromdate)
|
||||
|
||||
def test_set_autoreply_in_past(self):
|
||||
"""Create an autoreply with from date expired."""
|
||||
fromdate = timezone.localtime(
|
||||
timezone.now().replace(year=2014, month=1, day=1, hour=12, microsecond=0)
|
||||
)
|
||||
values = {
|
||||
"subject": "test",
|
||||
"content": "I'm off",
|
||||
"enabled": True,
|
||||
"fromdate": fromdate.strftime("%Y-%m-%d %H:%M:%S"),
|
||||
}
|
||||
self.ajax_post(reverse("autoreply"), values)
|
||||
account = User.objects.get(username="user@test.com")
|
||||
arm = models.ARmessage.objects.get(mbox=account.mailbox)
|
||||
self.assertEqual(timezone.localtime(arm.fromdate), fromdate)
|
||||
|
||||
def test_set_autoreply_dates(self):
|
||||
"""Create an autoreply with from and to dates."""
|
||||
fromdate = timezone.localtime(timezone.now())
|
||||
untildate = fromdate + datetime.timedelta(days=1)
|
||||
values = {
|
||||
"subject": "test",
|
||||
"content": "I'm off",
|
||||
"enabled": True,
|
||||
"fromdate": fromdate.strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"untildate": untildate.strftime("%Y-%m-%d %H:%M:%S"),
|
||||
}
|
||||
self.ajax_post(reverse("autoreply"), values)
|
||||
account = User.objects.get(username="user@test.com")
|
||||
arm = models.ARmessage.objects.get(mbox=account.mailbox)
|
||||
self.assertEqual(
|
||||
timezone.localtime(arm.fromdate), fromdate.replace(microsecond=0)
|
||||
)
|
||||
self.assertEqual(
|
||||
timezone.localtime(arm.untildate), untildate.replace(microsecond=0)
|
||||
)
|
||||
|
||||
|
||||
class RepairTestCase(ModoTestCase):
|
||||
"""Check repair command."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user