<NME> test_core.py
<BEF> """Tests for core application."""

import httmock

from django.core import management
from django.core.urlresolvers import reverse
from django.test import TestCase
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 LoadInitialDataTestCase(TestCase):
    """Try to change the default username."""

    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()
        self.assertIn("core", lc._parameters)
        self.assertIn("secret_key", lc._parameters["core"])


class ProfileTestCase(ModoTestCase):
    """Profile related tests."""
            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)

<MSG> Merge pull request #1068 from modoboa/fix/cleanlog

Fixed cleanlogs command.
<DFF> @@ -2,6 +2,8 @@
 
 import httmock
 
+from dateutil.relativedelta import relativedelta
+
 from django.core import management
 from django.core.urlresolvers import reverse
 from django.test import TestCase
@@ -42,8 +44,8 @@ class AuthenticationTestCase(ModoTestCase):
         self.assertTrue(response.url.endswith(reverse("core:dashboard")))
 
 
-class LoadInitialDataTestCase(TestCase):
-    """Try to change the default username."""
+class ManagementCommandsTestCase(TestCase):
+    """Test management commands."""
 
     def test_change_default_admin(self):
         """Use dedicated option."""
@@ -59,6 +61,15 @@ class LoadInitialDataTestCase(TestCase):
         self.assertIn("core", lc._parameters)
         self.assertIn("secret_key", lc._parameters["core"])
 
+    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)
+
 
 class ProfileTestCase(ModoTestCase):
     """Profile related tests."""

Merge pull request #1068 from modoboa/fix/cleanlog